# 《并发设计模式》第15章-两阶段终止模式-到底什么是两阶段终止模式
作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码获取地址:https://t.zsxq.com/0dhvFs5oR (opens new window)
沉淀,成长,突破,帮助他人,成就自我。
- 本章难度:★★☆☆☆
- 本章重点:以场景故事的形式介绍两阶段终止模式,掌握两阶段终止模式的核心原理与使用场景,重点理解两阶段终止模式要解决的问题,能够思考两阶段终止模式的核心流程,并能够将两阶段终止模式灵活应用到自身实际场景中。
大家好,我是冰河~~
很多小伙伴都知道,Java程序最终都是以线程的方式运行,而线程运行完毕则会停止。而停止线程却并非一件简单的事情,因为真正停止线程之前,需要考虑一些额外的事情,比如要停止的线程正处于阻塞状态、要停止的线程正在等待其他线程、要停止的线程还在执行任务等等,这些情况都要考虑,而不是简单粗暴的强行停止线程的运行。那如何优雅的停止线程呢?此时,就可以使用两阶段终止模式。
# 一、故事背景
这几天,小菜的都过的比较充实,心里也是非常高兴的,因为他已经学习了两种高并发设计模式:一种是不可变模式,一种是保护性暂挂模式,不仅知道了这两种并发设计模式的原理、使用案例,更学会了这两种设计模式的使用场景和实际项目中的落地方案。
这天,小菜下班回到家,打开电脑,正在认真总结和思考学过的两种并发设计模式,并且在自己的脑海中正在思考做一个什么样的项目,能够同时将学过的两种设计模式应用到项目中。正当小菜有点思考,正在用笔在本子上写自己的思路时,此时“叮铃铃”,手机响了。
小菜一看,“卧槽,是产品经理”,顿时小菜心里一万个“草泥马”在奔腾,虽然心里万般不爽,但小菜还是强压心中的怒火,接通了电话,还没等小菜说话,电话那头就传来声音:“小菜,生产环境出问题了,比较紧急,你回公司一趟吧,有些问题需要你处理下”。
“好,马上”,小菜立即挂掉了电话,此时小菜心里想:“平时就总喜欢留下我们加班,结果就没啥事儿,这次又要我们回去加班,还说什么生产环境出问题了,很紧急,能有什么事儿呢?我这都没收到报警通知”。
于是,小菜还是将自己的思路完整的写到了本子上之后,收拾自己的电脑,背上电脑包,走出了家门。。。
# 二、场景分析
当小菜正在思考如何使用学过的两种设计模式实现一个项目,并且正在本子上写自己的实现思路时,产品经理打来电话让小菜回公司处理问题。此时,产品经理相当于给了小菜一个通知,让其停下手上的事情转去做其他事情。但是小菜并没有立刻终止手上的事情,而是完成自己当前手上的任务之后,转而去公司处理其他事情。
其实,这整个过程多多少少就类似于并发设计模式中的两阶段终止模式,产品经理向小菜发出了一个通知,让其回公司处理问题,这相当于两阶段终止模式的准备阶段。而小菜完成手上的任务后,收拾好电脑,背上电脑包走出家门,去公司处理问题,这相当于两阶段终止模式的执行阶段。
所以,两阶段终止模式会分为准备阶段和执行阶段,准备阶段就是通知目标线程准备停止,这一阶段主要是设置一个标志变量指示目标线程可以准备停止了。而执行阶段则是检查准备阶段设置的线程停止标识和信号,在此基础上确定线程停止的时机,并适当进行一定的“清理”工作。
# 三、引入线程
当小菜正在本子上写自己的思路时,被产品经理通知去公司处理问题,此时,小菜就相当于执行任务的线程,而产品经理就相当于通知执行任务线程停止的另外一个线程。当小菜认真思考如何在一个项目中同时使用学过的两种设计模式,并且正在将其记录到本子上时,如图15-1所示。
在图15-1中,我们将小菜看成是一个执行任务的线程,小菜这个线程会不断的将自己对项目的实现思路记录到本子上。
这里我们思考一下,如何去打断小菜这个线程呢?有些人可能会想到用 interrupt()方法,但对并发编程有一定基础的小伙伴可能都知道, 其实interrupt() 方法是将一个处于等待状态的线程唤醒,只不过这种唤醒方式会导致线程抛出InterruptedException异常,从而导致对应的线程终止运行,但只要此异常被捕获并处理,那么线程依然可以继续运行。
如果产品经理通过电话通知小菜去公司处理问题时,如何让小菜这个线程能够接收到产品经理的发出的通知呢?这时,我们可以使用一个线程状态标志位进行控制,比如小菜正在向本子上记录实现思路的过程如图15-2所示。
如果线程的状态标志位为正在运行,则说明小菜这个线程正在正常运行,并且正在将自己对项目的实现思路不断的记录到本子上。
此时,产品经理通知小菜到公司处理问题,就相当于产品经理这个线程,要终止小菜当前正在执行的任务,也就是要终止小菜这个线程。那如何实现呢?其实很简单,就是产品经理这个线程要将小菜线程的状态标志位设置为停止,如图15-3所示。
# 查看全文
加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码