Java没有提供一种安全直接的方法来停止某个线程,但是Java提供了中断机制(Interruption),这是一种协作机制,能够使一个线程终止另一个线程的当前工作;
抢占式中断与协作式中断??
线程中断
Java中断机制是一种协作机制,也就是说通过中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。这好比是家里的父母叮嘱在外的子女要注意身体,但子女是否注意身体,怎么注意身体则完全取决于自己
中断相关API
public static boolean interrupted():测试当前线程是否已经中断。线程的中断状态由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)
public boolean isInterrupted():测试线程是否已经中断。线程的中断状态不受该方法的影响
public void interrupt():中断线程;interrupt方法是唯一能将中断状态设置为true的方法
当调用某个线程的stop()时如果这个线程处于RUNNABLE状态,stop()将会导致这个线程直接抛出java.lang.ThreadDeath的Error;
InterruptedException
当可能阻塞的方法声明中有抛出InterruptedException则暗示该方法是可中断的,如BlockingQueue#put、BlockingQueue#take、Object#wait、Thread#sleep等
Thread.interrupt VS Thread.stop
Thread.stop方法已经不推荐使用了;调用stop后,大部分Java字节码都有可能抛出错误,哪怕是简单的加法
最重要的就是interrupt中断需要程序自己去检测然后做相应的处理,而Thread.stop会直接在代码执行过程中抛出ThreadDeath错误,这是一个java.lang.Error的子类
【知识点】
- 当单线程的控制台程序由于发生了一个未捕获的异常而终止时,程序将停止运行;
- 调用interrupt并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息;
- 静态方法interrupted会将当前线程的中断状态清除;
- 如果线程由于执行同步的Socket I/O或者等待获得内置锁而阻塞,那么中断请求只能设置线程的中断状态,除此之外没有其他任何作用;
- Java中断模型中每个线程对象里都有一个boolean类型的标识(不一定就要是Thread类的字段,实际上也的确不是,这几个方法最终都是通过native方法来完成的),代表着是否有中断请求(该请求可以来自所有线程,包括被中断的线程本身)
【资料】