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

本文总阅读量
本文最后更新于2 分钟前,文中所描述的信息可能已发生改变。

两阶段终止含义

即分为两个阶段来终止线程,让线程自然的结束run方法。第一个阶段是线程t1向需要终止的t2线程发送终止请求,第二个阶段是t2线程响应中断请求,即自然的结束run方法。可以采用调用线程的实例方法interrupt()与自定义的中断标志位来先让线程从sleep状态变为Runnable进而变为Terminated状态正常结束run方法。

简单的示例

java
public void stopMode() throws InterruptedException {
    Thread thread1 = new Thread(() -> {
        Thread th = Thread.currentThread();
        while (!th.isInterrupted()){
            try {
                System.out.println("执行逻辑..");
                //每隔一秒执行一次
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
                //重置打断标记为true,使得线程正确终止
                th.interrupt();
            }
        }
    });
    thread1.start();
    TimeUnit.SECONDS.sleep(5);
    //主线程给t1发送打断请求
    thread1.interrupt();
}

更加优雅点的示例

java
public class Test{
    //自定义线程是否结束的标志位
    // 因为这样可以在不管有没有正常处理中断异常,都能使得线程正常结束
    private volatile boolean shutDown = true;
    private Thread thread;
    public void start(){
        if(shutDown){
            shutDown = false;
            thread = new Thread(()->{
                //为什么不使用thread.isInterrupted()来判断线程是否要执行中断
                while (!shutDown){
                    try {
                        work();
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        //抛出处理中断异常后JVM会重置中断标志位
                        e.printStackTrace();
                        //加了自定义标志位thread.interrupt()有没有都不影响线程结束
                        //因为是使用的是自定义标志位来进行判断
                        thread.interrupt();

                    }
                }
            });
            thread.start();
        }
    }
    private void work(){
        System.out.println("执行业务逻辑..");
    }
    public boolean isShutDown(){
        return shutDown;
    }
    public void shutDown(){
        //给其他线程调用,发送一个中断线程的请求
        //更改标志位
        shutDown = true;
        if(thread!=null){
            //发送设置中断标志位为true
            thread.interrupt();
        }
    }
}

静态方法Thread.interrupted()与实例方法isInterrupted()的区别

都是用于判断当前线程是否被打断,静态方法Thread.interrupted()不仅会读取打断标志的值还会重置该打断标志为false而实例方法isInterrupted()则是只读打断标志的值。

小结

通过两阶段终止模式可以优雅的停止线程,防止结束线程时未释放锁而发生死锁等问题。

参考文章

两阶段终止模式

通过自定义注解向Spring容器中注入个性化Bean
Spring中Bean的生命周期及其扩展点
Valaxy v0.18.5 驱动 | 主题 - Yun v0.18.5
本站总访问量
本站访客数 人次
本站已运行0 天0 小时0 分0 秒后缀