代码实现:
public class Thread11 {
public static void main(String[] args) throws InterruptedException {
TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();
twoPhaseTermination.start();
TimeUnit.SECONDS.sleep(3);
twoPhaseTermination.stop();
}
}
@Slf4j(topic = "c.Thread12:")
class TwoPhaseTermination {
Thread monitor; //监控线程
//启动监控线程
public void start() {
monitor = new Thread(() ->{
while (true){
Thread current = Thread.currentThread();
if(current.isInterrupted()){
log.debug("料理后事,处理后续流程");
break;
}
try {
/**
* 在情况1这种情况下被打断,线程会清除打断标记,并且会抛出异常
* 因此需要我们在catch进行处理,将打断标记置为true
*/
TimeUnit.SECONDS.sleep(1); //情况1
/**
* 情况2下打断不会清除线程打断标记
*/
log.debug("执行监控记录,线程此时正在正常运行中");//情况2
} catch (InterruptedException e) {
e.printStackTrace();
//重新设置打断标记
current.interrupt();
}
}
});
monitor.setName("monitor");
monitor.start();
}
//停止监控线程
public void stop() {
monitor.interrupt();
}
}
运行结果:
00:37:39.430 c.Thread12: [monitor] - 执行监控记录,线程此时正在正常运行中
00:37:40.444 c.Thread12: [monitor] - 执行监控记录,线程此时正在正常运行中
00:37:41.423 c.Thread12: [monitor] - 料理后事,处理后续流程
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at com.concurrent.classtset.TwoPhaseTermination.lambda$start$3(Thread11.java:39)
at com.concurrent.classtset.TwoPhaseTermination$$Lambda$1/1879492184.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
使用volatile优化两阶段打断
@Slf4j(topic = "c.Test1:")
public class Test1 {
public static void main(String[] args) throws InterruptedException {
TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();
twoPhaseTermination.start();
TimeUnit.SECONDS.sleep(3);
log.debug("主线程执行了打断");
twoPhaseTermination.stop();
}
}
@Slf4j(topic = "c.TwoPhaseTermination:")
class TwoPhaseTermination {
Thread monitor; //监控线程
private volatile static boolean falg= false;
//启动监控线程
public void start() {
monitor = new Thread(() -> {
while (true) {
if (falg) {
log.debug("被打断了料理后事");
break;
}
try {
TimeUnit.SECONDS.sleep(1);
log.debug("执行监控记录,线程此时正在正常运行中");
} catch (InterruptedException e) {
}
}
});
monitor.setName("monitor");
monitor.start();
}
//停止监控线程
public void stop() {
falg= true;
monitor.interrupt();
}
}