怎么关闭一个 Java 线程 ( Thread ) ? 噢,不,正确的问题是怎么正确的关闭一个 Java 线程?
这个问题是不是很简单? 很简单啊,不就是使用 Thread.stop()
方法么?
但是,根据 ORACLE 的更新文档 ,Thread.stop()
方法可能导致监视器对象被破坏。
因此,我们必须使用其它更安全的方法,或在 Thread.stop()
方法上做一些改变。
使用一个标志 ( Flag )
假设存在一个任务,这个任务并不会自己自动结束,因此我们必须找到一些方式来停止该线程。
为了方便你的理解,我们从创建和启动线程的类开始,一步一步讲解。
首先,我们需要一个原子性的标志 ( flag )
public class ControlSubThread implements Runnable {
private Thread worker;
private final AtomicBoolean running = new AtomicBoolean(false);
private int interval;
public ControlSubThread(int sleepInterval) {
interval = sleepInterval;
}
public void start() {
worker = new Thread(this);
worker.start();
}
public void stop() {
running.set(false);
}
public void run() {
running.set(true);
while (running.get()) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
Thread.currentThread().interrupt();
System.out.println(
"Thread was interrupted, Failed to complete operation");
}
// do something here
}
}
}
上面这段代码中,我们使用了 AtomicBoolean
而不是让 while
循环评估常量 true。
有了这个标志,我们就可以通过将其设置为 true/false 来启动/停止执行。
中断线程
当把 sleep()
设置为较长的间隔时,或者我们正在等待可能永远不会被释放的 锁 时会发生什么 ?
我们面临长期阻塞或永不干净的风险。
为了解决这类问题,我们可以创建一个 interrupt()
。
为了演示如何创建 interrupt()
,我们在刚刚的范例基础上添加一些方法和一个新标志。
public class ControlSubThread implements Runnable {
private Thread worker;
private AtomicBoolean running = new AtomicBoolean(false);
private int interval;
// ...
public void interrupt() {
running.set(false);
worker.interrupt();
}
boolean isRunning() {
return running.get();
}
boolean isStopped() {
return stopped.get();
}
public void run() {
running.set(true);
while (running.get()) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
Thread.currentThread().interrupt();
System.out.println(
"Thread was interrupted, Failed to complete operation");
}
// do something
}
}
}
上面这段代码中,我们添加了一个 interrupt()
方法,并在该方法中将运行标志设置为 false
,然后调用工作线程的 interrupt()
方法中断线程。
如果线程在调用此函数时处于休眠状态,则 sleep()
会退出并抛出一个 InterruptedException
异常,就像任何其它阻塞调用一样。
后记
哎,本来可以使用 Thread.stop()
解决的问题,结果为了考虑锁和监视器,整蛊了一个长的解决方案,这难道就是 Java 开发不能避免的?
最新评论
1.4 可以嘛?
可以
2022.06.06版本2022.1 临时激活码激活提示key is invalid 热心大佬提供的激活码里跟文章里的激活码是一样的 坐等lz掘地三尺
我打开绿色版,用配色方案的时候,还是弹出付费
非常好用,谢谢!lz好人一生平安!
感谢楼主
东西不错,希望能够继续保持
这个win版破解之后,就不要激活吧~