线程的中断指的是线程在运行过程中被强制打断。原来往往会使用stop()方法来强制停止某个线程,但由于stop()方法在中断线程之后,可能会使得被该线程锁定的对象无法解锁,导致这个线程既无法继续执行,也不释放锁定的资源而造成死锁。因此,stop()方法已经被废弃。
对于线程中断而言,普遍认为中断一个线程只是为了引起该线程的注意,告知该线程存在某种异常等待处理,而被中断线程可以决定如何应对中断。因为在运行过程中某些线程可能非常重要,以至于它们不能被中断,可以不理会中断,仅仅在发现中断请求后抛出一些信息,然后继续执行。所以,出于对线程安全性的考虑,JDK采用一个变量来标识某个线程是否应该停止运行,是否存在中断请求,但线程是否中断,这取决于线程自身。
线程的中断操作将使用到表12.4中的方法。
表12.4 线程中断的方法
表12.4中的interrupt()方法可用于中断线程,该方法会将该线程的中断标志位设置为true。但是,线程被中断之后是什么状态并不能确定。在线程运行过程中,线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true),而不会像stop()方法那样直接中断一个正在运行的线程。
另外,判断某个线程是否中断,可以使用Thread.currentThread().isInterrupted()方法(先获得当前线程,再读取线程的中断状态),也可以使用Thread.interrupted()静态方法。一般情况下,建议采用前者,因为前者返回线程中断标志位之后,不会清除中断标志,即不会将中断标设置为false,而静态方法Thread.interrupted()在返回线程中断标志位之后,会将该线程的中断标志位清除,即重新设置为false。
说明:
如果一个线程处于等待状态(如线程调用了sleep()、join()、wait()等方法),且线程在检查中断标示时发现中断标示为true,则线程会在这些方法的调用处抛出InterruptedException异常,并且在抛出异常后立即将线程的中断标志位清除,即重新设置为false。
【例12.5】创建一个自定义线程MyThread,然后不断输出线程状态。在MyThread执行过程中,将线程中断标志位设置为true,看看线程运行情况。
在cn.pzhu.op包下创建一个名为ThreadInterrupt的类,关键代码如下:(www.daowen.com)
MyThread类实现了Runnable接口,并且覆写了run()方法。该线程每隔1000ms会输出当前线程的状态。线程将重复执行5次输出,5次输出完毕后结束。
在main()方法中创建了MyThread类的实例my,然后启动了这个线程。主线程中定义了一个变量n作为计时器,n从0开始计数,每隔500ms累加1。当++n>3时,主线程中调用my.interrupt()方法将my线程中断,然后主线程执行完毕。
运行上述代码,程序运行结果如图12.12所示。
从图12.12可以看出,当MyThread类的实例my启动之后,线程my每隔1000ms会输出前状态。在主线程没有中断my线程之前(当++n<=3时),my线程的状态都是“RUNNABLE”;当my线程被主线程中断之后,my线程的中断状态为true。之后,由于线程my调用了sleep()方法进入等待状态,这时my线程发现线程的中断标志位为true,抛出InterruptedException异常,且立即将中断标志位置为false,然后线程继续执行,之后my线程状态又恢复为“RUNNABLE”。
说明:因JavaIO的输出耗时不确定,因此输出异常的顺序可能与图中运行结果不一样,这是正常现象。
图12.12 程序运行结果
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。