所谓优雅停止,即即将在停止的线程足够的时间完成善后工作,而不是直接杀死线程。假设此时某线程正在独占资源(占有锁),突然对线程的终止,会导致其占有的资源无法得到释放,其他线程将无法获取该资源。
package cn.yds.juc.learning;
import lombok.extern.slf4j.Slf4j;
/**
* @author yds
* @Date 2022/9/21 19:43
* @Description 两阶段终模式
* @Version 1.0.0
*/
public class ThreadDemo5 {
public static void main(String[] args) throws InterruptedException {
ThreadTwoPhaseTermination phaseTermination = new ThreadTwoPhaseTermination();
phaseTermination.start();
Thread.sleep(10000);
phaseTermination.stop();
}
}
@Slf4j(topic = "ThreadTwoPhaseTermination")
class ThreadTwoPhaseTermination{
private Thread monitor;
/**
* 开启监控线程
*/
public void start(){
monitor = new Thread(()->{
while (true){
Thread thread = Thread.currentThread();
if (thread.isInterrupted()){
log.debug("料理后事");
break;
}
try {
Thread.sleep(2000);//情况一:此处被打断,打断标记会被清空(false).所以要在catch中重新设置
log.debug("执行监控记录");//情况二:此处被打断,打断标记是true,下次循环就退出了
} catch (InterruptedException e) {
e.printStackTrace();
//重置打断标记为true
thread.interrupt();
}
}
});
monitor.start();
}
/**
* 停止监控线程
*/
public void stop(){
monitor.interrupt();
}
}
演示:
14:43:02.841 [Thread-0] DEBUG ThreadTwoPhaseTermination - 执行监控记录
14:43:04.848 [Thread-0] DEBUG ThreadTwoPhaseTermination - 执行监控记录
14:43:06.851 [Thread-0] DEBUG ThreadTwoPhaseTermination - 执行监控记录
14:43:08.853 [Thread-0] DEBUG ThreadTwoPhaseTermination - 执行监控记录
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at cn.yds.juc.learning.ThreadTwoPhaseTermination.lambda$start$0(ThreadDemo5.java:38)
at java.lang.Thread.run(Thread.java:748)
14:43:10.840 [Thread-0] DEBUG ThreadTwoPhaseTermination - 料理后事 开始