并发编程

并发编程原理和应用
帅旋
关注
充电
IT宅站长,技术博主,架构师,全网id:arthinking。

如何优雅的中断线程

发布于 2020-03-15 | 更新于 2024-05-16

中断一个线程,我们可能最先想到的是stop方法。但是我们可以发现,这个方法以及被废弃了?

1、为什么不能使用stop中断线程?

stop掉一个线程,会是他解锁所有已经获取到的锁。突然不安全的解锁了锁,可能导致某些数据被损坏,这些破坏性的行为是无法预测的,进而导致各种奇怪的行为。

设想一下:杀死一个正在将文件写入磁盘的线程,您可能最终会损坏这个文件。

所以,这个方法被弃用了,那有没有什么其他方法呢,接下来就进行说明。

2、Thread.interrupt()信号

该方法会把线程的中断状态位设置为true,不会直接中断了线程的执行。

2.1、如何判断线程是否被发送了中断请求?

一般用Thread.currentThread().isInterrupted()方法进行判断,一般常用做法是在循环条件中进行判断,如果未被中断则继续执行后续的工作:

1
2
3
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()重新设置中断标识。

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/cpj/how-to-interrupt-threads-gracefully.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。