并发编程模式 - Two-Phase Termination两阶段终止模式

本文介绍如何通过线程及线程池提供的API来终止正在执行的任务,并探讨了自定义中断标志位的重要性,以确保在线程或线程池任务中断时能够正确响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    当需要对正在执行指令的线程(或线程池任务)执行终止操作时,可以直接调用线程或线程池提供的Api,

1、线程

    Thread提供了stop方法,强制停止正在执行的线程任务,除非自己的任务正执行一半可以被停止【比如采集日志本身就允许采样率等】。否则一般可以使用interrupt方法执行终端操作。

2、线程池

    线程池(如ThreadPoolExecutor 父类ExecutorService)提供了shutdown方法,在执行完任务后自动关闭线程。当然我们也可以暴力的使用shutdownNow方法,使用场景如上,或者在下一次线程池启动时能将上次的任务执行完成。

 

但是需要注意,线程的生命周期是 start启动后,就进入runnable允许CPU时间切片切中运行,也运行进入Blocking状态,那么我们需要将线程进行终止则需要将Blocking状态的线程切换为Runnable状态才能进行关闭。

 

    实现终止任务的模式,一般的做法是设置一个标志位,线程会在执行任务的时候找个合适的位置检查标志位,如果标志位发发生了变化,则终止我们正在执行的任务,后面的阶段称为响应终止指令,这就是两阶段终止模式。

    我们可以直接使用线程或线程池原生的Api即可达到终止正在执行线程池的任务,但是线上项目的环境是非常复杂的,我们没有办法保证第三方类库在获取到终端异常后,会重新设置标志位,(即第三方类库将Interrupt异常吃掉了),所以一般都是使用自己的终端标志位,如

/** 设置自己的中断标志位 */
private volatile boolean terminated = false;

   所以最终写法大致类似:

public class TerminatedTwoStageTermination {
    /** 设置自己的中断标志位 */
    private volatile boolean terminated = false;
    boolean started = false;
    /** 采集线程 */
    Thread rptThread;

    public synchronized void start() {
        // 只能启动一个监控线程
        if (started) {
            return;
        }
        started = true;
        terminated = false;
        rptThread = new Thread(() -> {
            while (!terminated) {
                // 采集工作
                report();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    // 重新设置自己的中断标志位
                    Thread.currentThread().interrupt();
                }
            }
            started = false;
        });
        rptThread.start();
    }

    public synchronized void stop() {
        // 设置自己的中断标志位
        terminated = true;
        // 中断线程,即使是 TIMED_WAITING状态的线程,然后进行下一次判断 自己的终止标志位 terminated
        rptThread.interrupt();
    }
    /** 模拟执行任务 */
    private void report() {
    }
}

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值