中断的原理
Java中断机制是一种协作机制,中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。
java.lang.Thread类提供了几个方法来操作这个中断状态,这些方法包括:
public static boolean interrupted()
测试当前线程是否已经中断。线程的中断状态由该方法清除。
public boolean isInterrupted()
测试线程是否已经中断。线程的中断状态不受该方法的影响。
public void interrupt()
中断线程
线程1通过调用interrupt方法将线程2的中断状态置为true,2可以在合适的时候调用interrupted或isInterrupted来检测状态并做相应的处理。
类库中的有些类的方法也可能会调用中断:
如FutureTask中的cancel方法,如果传入的参数为true,它将会在正在运行异步任务的线程上调用interrupt方法,
如果正在执行的异步任务中的代码没有对中断做出响应,那么cancel方法中的参数将不会起到什么效果;
又如ThreadPoolExecutor中的shutdownNow方法会遍历线程池中的工作线程并调用线程的interrupt方法来中断线程,
所以如果工作线程中正在执行的任务没有对中断做出响应,任务将一直执行直到正常结束。
thread.stop():
线程会马上停止,但是可能导致数据不同步,或者资源得不到回收的问题而且stop已经标注为作废方法,所以使用一定要慎重。
中断的处理
interrupt()方法仅仅是在当前线程中打了一个停止的标识将中断标志修改为true,并没有真正的停止线程:
如果在此基础上进入堵塞状态(sleep(),wait(),join()),马上就会抛出一个InterruptedException,
且中断标志被清除,重新设置为false,线程退出。
如果遇到的是可中断的阻塞方法抛出InterruptedException:
可以继续向上层抛出该异常。
若有时候不太方便在方法上抛出InterruptedException,比如要实现的某个接口中的方法签名上没有throws InterruptedException,
这时就可以捕获可中断方法的InterruptedException并且恢复异常(重新设置中断)。
中断的响应:
有些程序可能一检测到中断就立马将线程终止,有些可能是退出当前执行的任务,继续执行下一个任务……
作为一种协作机制,这要与中断方协商好,当调用interrupt会发生些什么都是事先知道的,如做一些事务回滚操作,一些清理工作,一些补偿操作等。
若不确定调用某个线程的interrupt后该线程会做出什么样的响应,那就不应当中断该线程。
中断的使用
- 点击某个桌面应用中的取消按钮时;
- 某个操作超过了一定的执行时间限制需要中止时;
- 多个线程做相同的事情,只要一个线程成功其它线程都可以取消时;
- 一组线程中的一个或多个出现错误导致整组都无法继续时;
- 当一个应用或服务需要停止时。