介绍
话不多说,先看图理解
为什么
为什么,需要这个模式呢?存在的意义是什么?
作用是优雅的停止一个线程,让其有“料理后事”的功能。有人会说,我用stop()方法,不是一样可以停止这个线程吗?这是不可行的,因为会直接正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁,其它线程将永远无法获取锁。所以,两阶段终止模式就来啦!
是什么
这个模式主要就是基于线程中的打断方法interrupt():如果打断的是sleep,wait,join,则会导致该线程抛出打断异常,并清楚打断标记。如果打断这在运行的线程,则会设置打断标记为true。这个两阶段也正是指该线程处于的两种阶段,一种是正常运行,一种是sleep等阻塞状态。
isinterrupted()判断当前线程是否被打断,不会清楚打断标记
interupted()判断当前线程是否被打断,会清楚打断标记(不常用)
ok,通过上面这两个方法,就可以实现,让线程自己去优雅的停止。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
@Slf4j(topic = "c.TPTInterrupt") class TPTInterrupt { private Thread thread; public void start(){ thread = new Thread(() -> { while(true) { Thread current = Thread.currentThread(); if(current.isInterrupted()) { log.debug("料理后事"); break; } try { //对应两阶段,该线程处于sleep等状态,被打断,打断标记为false,抛出异常,再次打断,标记为true Thread.sleep(1000); //该线程处于正常运行状态,被打断,则打断标记为true, log.debug("将结果保存"); } catch (InterruptedException e) { current.interrupt(); } } },"监控线程"); thread.start(); } public void stop() { thread.interrupt(); } } |
调用
1 2 3 4 5 |
TPTInterrupt t = new TPTInterrupt(); t.start(); Thread.sleep(3500); log.debug("stop"); t.stop(); |
结果
1 2 3 4 5 |
11:49:42.915 c.TwoPhaseTermination [监控线程] - 将结果保存 11:49:43.919 c.TwoPhaseTermination [监控线程] - 将结果保存 11:49:44.919 c.TwoPhaseTermination [监控线程] - 将结果保存 11:49:45.413 c.TestTwoPhaseTermination [main] - stop 11:49:45.413 c.TwoPhaseTermination [监控线程] - 料理后事 |