java 两阶段终止线程的正确做法

 更新时间:2021年12月12日 11:49:44   作者:bkpp976  
这篇文章主要给大家分享了java 两阶段终止线程的正确做法,文章列举出错误的做法与正确做法做对比,具有一定的参考价值,需要的小伙伴可以参考一下,希望对你有所帮助

一、怎么优雅地关闭一个线程?

在一个线程T1中如何优雅地关闭线程T2(也就是说要给T2一个机会释放持有的资源)?

1.错误做法

使用stop()方法停止线程:

stop()方法会真正杀死线程,如果此时该线程持有锁,那么其他线程将永远无法获取锁。

使用System.exit()方法停止线程:

会让整个进程都退出

2.正确做法

思路:

代码实现:

public class Test {
    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();
        twoPhaseTermination.start();

        Thread.sleep(3000);
        twoPhaseTermination.stop();

    }
}

class TwoPhaseTermination{
    // 监控线程
    private Thread monitorThread;

    public void start(){
        monitorThread = new Thread(()->{
            Thread current = Thread.currentThread();
            while(true){
                if(current.isInterrupted()){

                    System.out.println("线程要关闭了...");
                    break;
                }
                try {
                    Thread.sleep(1000); // 阶段1
                    System.out.println("监控线程正在工作...."); // 阶段2
                     // 如果在阶段2被打断,线程的isInterrupted标志位为true,会捕抓到信号并关闭线程
                     // 如果在阶段1被打断,会进入catch语句块,并且isInterrupted标志位清空,无法关闭线程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    // 需要重新设置isInterrupted标志位为true
                    monitorThread.interrupt();
                }
            }

        });
        // 启动线程
        monitorThread.start();
    }

    public void stop(){
        // 设置isInterrupted标志位true
        monitorThread.interrupt();
    }
}

运行结果:

两阶段关闭线程:

二、要点

为什么需要在catch代码块中重新执行monitorThread.interrupt()?因为Thread.sleep()执行过程中被打断,isInterrupted标志位会清空,下一次进入while循环就会忽略这次打断,继续运行线程。

演示一下把monitorThread.interrupt()注释掉的结果:

可以看到,会忽略这次的isInterrupted信号,继续运行线程。

到此这篇关于java 两阶段终止线程的正确做法的文章就介绍到这了,更多相关java 两阶段终止线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解读nacos获取配置文件的大致过程

    解读nacos获取配置文件的大致过程

    这篇文章主要介绍了nacos获取配置文件的大致过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • log4j的配置文件详细解析

    log4j的配置文件详细解析

    以下小编主要为大家介绍一下log4j的配置文件各个配置项的含义。需要的朋友可以过来参考下
    2013-08-08
  • Java实现对比两个实体类字段变化的示例详解

    Java实现对比两个实体类字段变化的示例详解

    我们在工作中,可能会在日志中记录数据的变化情况或者在公共处理的数据增加一个日志页面,我们可以根据CompareUtils工具类比较数据前后发生了怎样的变化,下面我们就来看看具体实现吧
    2024-03-03
  • Java使用Optional实现优雅避免空指针异常

    Java使用Optional实现优雅避免空指针异常

    空指针异常(NullPointerException)可以说是Java程序员最容易遇到的问题了。为了解决这个问题,Java 8 版本中推出了 Optional 类,本文就来讲讲如何使用Optional实现优雅避免空指针异常吧
    2023-03-03
  • Object类wait及notify方法原理实例解析

    Object类wait及notify方法原理实例解析

    这篇文章主要介绍了Object类wait及notify方法原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • 详解Log4j 日志文件存放位置设置

    详解Log4j 日志文件存放位置设置

    这篇文章主要介绍了详解Log4j 日志文件存放位置设置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 深入理解HashMap各个方法的源码

    深入理解HashMap各个方法的源码

    这篇文章主要介绍了深入理解HashMap各个方法的源码,HashMap初始容量不能为负数,若初始容量大于最大容量,则让它等于最大容量,负载因子必须大于0,并且传入的initialCapacity不是HashMap的容量大小,需要的朋友可以参考下
    2023-12-12
  • SpringSecurity OAtu2+JWT实现微服务版本的单点登录的示例

    SpringSecurity OAtu2+JWT实现微服务版本的单点登录的示例

    本文主要介绍了SpringSecurity OAtu2+JWT实现微服务版本的单点登录的示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Spring多个数据源配置详解

    Spring多个数据源配置详解

    在实际场景中,会有需要配置多个数据源的场景,本文就介绍一下如何配置Spring多数据源,具有一定的参考价值,感兴趣的可以了解一下
    2021-08-08
  • springboot log多环境配置方式

    springboot log多环境配置方式

    这篇文章主要介绍了springboot log多环境配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06

最新评论