中断I/O操作
然而,如果线程在I/O操作进行时被阻塞,又会如何?I/O操作可以阻塞线程一段相当长的时间,特别是牵扯到网络应用时。例如,服务器可能需要等待一个请求(request),又或者,一个网络应用程序可能要等待远端主机的响应。
如果你正使用通道(channels)(这是在Java 1.4中引入的新的I/O API),那么被阻塞的线程将收到一个 ClosedByInterruptException异常。如果情况是这样,其代码的逻辑和第三个例子中的是一样的,只是异常不同而已。
但是,你可能正使用Java1.0之前就存在的传统的I/O,而且要求更多的工作。既然这样,Thread.interrupt()将不起作用,因为线程将不会退出被阻塞状态。Listing D描述了这一行为。尽管interrupt()被调用,线程也不会退出被阻塞状态。
Listing D
import java.io.*;
class Example4 extends Thread {
public static void main( String args[] ) throws Exception {
Example4 thread = new Example4();
System.out.println( "Starting thread..." );
thread.start();
Thread.sleep( 3000 );
System.out.println( "Interrupting thread..." );
thread.interrupt();
Thread.sleep( 3000 );
System.out.println( "Stopping application..." );
//System.exit( 0 );
}
public void run() {
ServerSocket socket;
try {
socket = new ServerSocket(7856);
} catch ( IOException e ) {
System.out.println( "Could not create the socket..." );
return;
}
while ( true ) {
System.out.println( "Waiting for connection..." );
try {
Socket sock = socket.accept();
} catch ( IOException e ) {
System.out.println( "accept() failed or interrupted..." );
}
}
}
}
很幸运,Java平台为这种情形提供了一项解决方案,即调用阻塞该线程的套接字的close()方法。在这种情形下,如果线程被I/O操作阻塞,该线程将接收到一个SocketException异常,这与使用interrupt()方法引起一个InterruptedException异常被抛出非常相似。
唯一要说明的是,必须存在socket的引用(reference),只有这样close()方法才能被调用。这意味着socket对象必须被共享。Listing E描述了这一情形。运行逻辑和以前的示例是相同的。
Listing E
import java.net.*;
import java.io.*;
class Example5 extends Thread {
volatile boolean stop = false;
volatile ServerSocket socket;
public static void main( String args[] ) throws Exception {
Example5 thread = new Example5();
System.out.println( "Starting thread..." );
thread.start();
Thread.sleep( 3000 );
System.out.println( "Asking thread to stop..." );
thread.stop = true;
thread.socket.close();
Thread.sleep( 3000 );
System.out.println( "Stopping application..." );
//System.exit( 0 );
}
public void run() {
try {
socket = new ServerSocket(7856);
} catch ( IOException e ) {
System.out.println( "Could not create the socket..." );
return;
}
while ( !stop ) {
System.out.println( "Waiting for connection..." );
try {
Socket sock = socket.accept();
} catch ( IOException e ) {
System.out.println( "accept() failed or interrupted..." );
}
}
System.out.println( "Thread exiting under request..." );
}
}
以下是运行Listing E中代码后的输出:
Starting thread...
Waiting for connection...
Asking thread to stop...
accept() failed or interrupted...
Thread exiting under request...
Stopping application...
多线程是一个强大的工具,然而它正呈现出一系列难题。其中之一是如何中断一个正在运行的线程。如果恰当地实现,使用上述技术中断线程将比使用Java平台上已经提供的内嵌操作更为简单。
分享到:
相关推荐
例如,如果线程正在写入共享数据,突然被终止,那么数据可能处于不一致的状态,导致后续程序出错。因此,我们应该尽量设计线程,使其能够自我检查并决定何时停止工作,而不是直接强制中断。 一种常见的方法是使用...
3. 如果线程正在执行阻塞IO操作,则对应的IO通道将被关闭,并抛出`ClosedByInterruptException`。 4. 如果线程当前不在阻塞状态,那么仅设置其中断状态。 #### 四、注意事项 1. **中断状态的检查与清除**:在处理...
在C语言中,正确终止正在运行的子线程是非常重要的,以免出现内存泄露等问题。下面是关于C语言正确终止正在运行的子线程的知识点总结: 1. 使用exit函数:任何一个线程调用exit都会导致进程结束,各种子线程当然也...
如果你的线程正在操作临界资源,很有可能会造成资源没有正确释放而出现死锁问题。正确的做法应该是使用标记来终止线程的执行。 基本思路是:定义一个用于描述“停止”信号的变量,在整个程序启动前,设置该变量为...
- **线程安全**:直接终止可能导致正在执行的关键操作被打断,引发数据不一致。 - **资源泄露**:线程可能持有资源,如文件句柄、数据库连接,未正常关闭会导致资源泄露。 - **死锁**:如果线程在等待其他线程...
想要终止线程的运行,可以使用以下方法: 1、线程函数...1、线程函数返回 始终都应该将线程设计成这样的形式,即当想要线程终止运行时,它们就能够返回。这是确保所有线程资源被正确地清除的唯一办法。 如果线程能够返
终止线程是指强制结束线程的执行,使其不再继续运行。在C#中,直接使用`Thread.Abort()`方法可以尝试终止线程。然而,这是一个非常危险的操作,因为线程可能在被终止时正在执行清理工作,如释放资源。因此,除非你...
线程现在会运行到`ThrowFun`,并抛出预设的异常,从而引发线程的终止。 然而,如果线程已经阻塞,上述方法可能无法执行。为了防止线程进入阻塞状态,我们需要采取一些措施: 1. 替换阻塞函数:对于长时间阻塞的...
这些线程可以并行运行,执行不同的任务。 要实现“可以单独关闭和运行”的功能,我们需要在每个工作类中定义相应的信号(Signals)和槽(Slots)。信号是Qt中的事件机制,当某个条件满足时,可以触发信号;而槽是...
标题“易语言判断多线程是否运行结束”所指的,就是在多线程环境下,编写代码来检测一个特定线程是否已经完成了它的执行任务,即线程是否已经终止。这在等待所有线程完成、线程间同步或者资源释放等场景下非常有用。...
9. **线程的终止**: - 通过`TerminateThread`函数可以直接结束线程,但这种方法应谨慎使用,因为它可能不给线程提供清理机会。更安全的方式是在线程函数中设置一个退出标志,由线程自己退出。 10. **等待线程结束...
此命令会返回一个整数值,表示线程的状态,如0表示未启动,1表示正在运行,2表示等待,3表示已结束等。 3. **子程序设计**: - 在“子程序1”中,通常会实现线程的主要功能,比如执行特定任务、处理数据等。子程序...
Java实现终止线程池中正在运行的定时任务 Java中实现终止线程池中正在运行的定时任务是Java多线程编程中一个常见的问题。本篇文章将详细介绍如何实现终止线程池中正在运行的定时任务,并提供相应的代码示例。 首先...
首先,线程的挂起是指将一个正在运行的线程暂停执行,使其进入等待状态。这通常用于临时让出CPU资源,等待某些条件满足后再继续执行。在Java中,可以使用`Thread.suspend()`方法来挂起线程,但需要注意,这个方法会...
// 允许C运行时库进行清理,并退出线程 _endthreadex(nExitCode); } ``` 通过以上代码可以看出,`AfxEndThread`函数首先执行了一些清理工作,比如释放了`CWinThread`对象,并调用了`_endthreadex`函数来终止线程...
在进行线程管理和终止时,需要谨慎操作,因为不恰当地终止线程可能会导致数据不一致或者影响到其他正常运行的服务。通常,在终止线程前,先尝试优化查询或解决引起问题的根本原因更为理想。 总之,`SHOW ...
在MFC中,CWinThread类提供了StartThread()函数来启动线程,而AfxEndThread()用于终止线程。线程的暂停和恢复可以通过挂起(SuspendThread)和恢复(ResumeThread)API来实现,但需要注意的是,挂起线程可能会导致...
在Java多线程编程中,终止一个线程并非像许多人所理解的那样简单直接。线程的"中断"并不是让线程立即停止执行,而是一个标志,用来指示线程应该中断其当前活动并采取相应措施。Java提供了多种方法来处理线程的中断,...