多线程设计模式-两阶段终止模式

定义:通过将停止线程这个动作分解为准备阶段和执行阶段两个阶段,提供了一种通用的用于优雅地停止线程的方法
准备阶段:“通知”目标线程(欲停止的线程)准备进行停止,会设置一个标志变量用于指示目标线程可以准备停止了
停止阶段:检查准备阶段所设置的线程停止标志和信号,在此基础上决定线程停止的时机,并进行适当的“清理”操作

两阶段终止模式UML图

ThreadOwner: 目标线程的拥有者。一般讲目标线程的创建者视为该线程的拥有者,并假定其“知道”目标线程的工作内容,可以安全地停止目标线程
Terminatable: 可停止线程的抽象
    terminate: 请求目标线程终止
AbstractTerminatableThread: 可停止的线程
    terminate: 设置线程停止标志,并发送停止“信号”给目标线程
    doTerminate: 留给子类实现线程停止时所需的一些额外操作,如目标线程代码中包含Socket I/O,子类可以在该方法中关闭socket以达到快速停止线程,而不会使目标线程等待I/O完成才能侦测到线程停止标记
    doRun: 线程处理逻辑方法。留给子类实现线程的处理逻辑,相当于Thread.run(),只不过该方法中无须关心停止线程的逻辑,因为这个逻辑已经被封装在TerminatableThread的run方法中
    doCleanup: 留给子类实现线程停止后可能需要的一些清理动作
TerminationToken: 线程停止标志。toShutdown用于指示目标线程可以停止了。reservations可用于反映目标线程还有多少数量未完成的任务,以支持等目标线程处理完任务后再进行停止
ConcreteTerminatableThread: 由应用自己实现的AbstractTerminatableThread参与者的实现类。该类需要实现其父类的doRun()抽象方法,在其中实现线程的处理逻辑,并根据应用的实际需要覆盖其父类的doTerminate方法、doCleanup方法

下列代码中告警发送线程停止需要解决两个问题,一个是将缓存队列中的消息发送出去,一个是用于缓存消息的阻塞队列为空时发送线程会处于等待状态,无法响应关闭线程的请求,因此此处使用两阶段终止模式来解决这个问题。设置一个计数器reservations,消息缓存到队列是加1,消息发送成功是减1,如果值为0,则可以确定线程无未处理任务,可以关闭。执行终止方法AbstractTerminatableThread#terminate()时先将标记toShutdown设置为true,此为准备阶段,然后执行终止逻辑,如果缓存队列中无待处理的任务,则强制终止线程(即调用super.interrupt()方法)。执行阶段AbstractTerminatableThread#run()会判断toShutdown和resvations的值进行终止线程,然后还会执行一些清理。

package com.bruce.twoPhaseTermination;
/**
* @Author: Bruce
* @Date: 2019/5/31 12:31
* @Version 1.0
*/
public interface Terminatable {
    void terminate();
}
package com.bruce.twoPhaseTermination;

import java.lang.ref.WeakReference;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;

/**
* @Author: Bruce
* @Date: 2019/5/31 12:55
* @Version 1.0
*/
public class TerminationToken {
    protected volatile boolean toShutdown = false;

    public final AtomicInteger reservations = new AtomicInteger(0);

    private final Queue<WeakReference<Terminatable>> coordinatedThreads;

    public TerminationToken() {
        coordinatedThrea
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值