中断一个线程,我们可能最先想到的是stop方法。但是我们可以发现,这个方法以及被废弃了?
1、为什么不能使用stop中断线程?
stop掉一个线程,会是他解锁所有已经获取到的锁。突然不安全的解锁了锁,可能导致某些数据被损坏,这些破坏性的行为是无法预测的,进而导致各种奇怪的行为。
设想一下:杀死一个正在将文件写入磁盘的线程,您可能最终会损坏这个文件。
所以,这个方法被弃用了,那有没有什么其他方法呢,接下来就进行说明。
2、Thread.interrupt()信号
该方法会把线程的中断状态位设置为true,不会直接中断了线程的执行。
2.1、如何判断线程是否被发送了中断请求?
一般用Thread.currentThread().isInterrupted()
方法进行判断,一般常用做法是在循环条件中进行判断,如果未被中断则继续执行后续的工作:
1 | while(!Thread.currentThread().isInterrupted() && 还有其他工作要做){ |
2.2、处于阻塞的线程接收到中断信号会抛异常
由以下方法导致的阻塞:Thread.sleep
, Thread.join
, Thread.wait
等,会在接收到中断请求后会抛出InterruptedException
异常,抛出异常的同时会将线程中断标识位清除。至于抛出异常后,程序要如何处理,则交由程序员来处理。
2.3、在锁中使用中断
synchronized锁的底层实现方式决定了其是无法响应中断的。
ReentrantLock的lock()方法也是无法响应中断的。不过tryLock和lockInterruptibly却可以响应中断,这对处理死锁问题比较有用。具体实现则用到了interrupt和响应interrupt,可以阅读源码进一步了解。
2.4、底层如何处理中断
最好不要在底层把中断处理掉。可以往上抛异常,或者调用Thread.currentThread.interrupt()
重新设置中断标识。