Java多线程中停止线程遇到线程阻塞的处理方法详解

 更新时间:2023年10月26日 11:02:43   作者:java持续实践  
这篇文章主要介绍了Java多线程中停止线程遇到线程阻塞的处理方法详解,在阻塞状态下,线程会释放CPU资源,从而允许其他线程执行,线程阻塞是实现多线程编程中重要的概念,可以提高程序的效率和资源利用率,需要的朋友可以参考下

Java多线程中停止线程遇到线程阻塞的处理方法详解

线程可能被阻塞

子线程sleep的过程中, 给出中断信号的demo

当子线程正在休眠的过程中, 去进行线程的中断. 因此主线程要等子线程执行到 Thread.sleep(1000);这一行代码,因此在main线程中, 给出了Thread.sleep(500);

public class RightWayStopThreadWithSleep {


    public static void main(String[] args) throws InterruptedException {

        // 创建线程任务
        Runnable runnable = () -> {
            int num = 0;
            try {
                while (num <= 300 && !Thread.currentThread().isInterrupted()) {
                    if (num % 100 == 0) {
                        System.out.println(num + " 是100的整数");
                    }
                    num++;
                }

                //执行完成循环累加后, 执行sleep, 此时主线程给出中断信号
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        };

        //启动线程
        Thread thread = new Thread(runnable);

        thread.start();

        //当子线程 正在休眠的过程中, 去进行线程的中断.
        //因此要等子线程执行到  Thread.sleep(1000);这一行代码
        //此处的  Thread.sleep(500); 是给子线程  循环0到300的时间用的
        Thread.sleep(500);

        //子线程执行完成0到300累加后, 在子线程sleep的过程中, 去给出中断的信号
        thread.interrupt();
    }
}

程序执行的结果如下 :

可以看到 当子线程执行完循环的任务后 ,响应主线程的中断信号的方式为 抛出异常. 那是因为在子线程中, sleep方法被try catch所包裹了, 面对在sleep中,这种类似的阻塞操作的时候, 就会catch出这个异常, 打印如下的异常 ,响应中断 java.lang.InterruptedException: sleep interrupted 通过断点调试可以看到, 进入了catch的代码块.

而如果子线程没有阻塞的状态, 那么子线程即使收到了中断的信号, 也不会抛出异常.

如果线程在每次迭代时都阻塞

线程在每次迭代时都阻塞的代码如下. 在子线程循环的过程中, 每次都Thread.sleep(10); 休眠10ms. 在子线程运行5s,后, 主线程给子线程发出中断的通知.

public class RightWayStopThreadWithSleepEveryLoop {

    public static void main(String[] args) throws InterruptedException {

        // 创建线程任务
        Runnable runnable = () -> {
            int num = 0;
            try {
                while (num <= 10000 && !Thread.currentThread().isInterrupted()) {
                    if (num % 100 == 0) {
                        System.out.println(num + " 是100的整数");
                    }
                    num++;
                    //每一次循环,休眠10ms
                    Thread.sleep(10);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        //启动线程
        Thread thread = new Thread(runnable);
        thread.start();

        //此处的  Thread.sleep(5000); 是休眠主线程, 让子线程运行5s,
        //子线程运行5s后, 给出子线程的休眠信号
        Thread.sleep(5000);
        thread.interrupt();
    }
}

此时打印如下. 子线程打印出来sleep过程中被中断的异常

与上一节线程可能被阻塞的区别是, 此时由于每一次的循环,都会sleep, 因此真正判断子线程是否被中断, 不是使用Thread.currentThread().isInterrupted(), 而是在Thread.sleep(10); 休眠的过程中, 就能立刻的感知到了中断通知, 就会抛出异常. 因此可以把代码修改如下, 在子线程的while (num <= 10000) 时, 就不需要进行判断线程是否中断了.

public class RightWayStopThreadWithSleepEveryLoop {


    public static void main(String[] args) throws InterruptedException {

        // 创建线程任务
        Runnable runnable = () -> {
            int num = 0;
            try {
                while (num <= 10000) {
                    if (num % 100 == 0) {
                        System.out.println(num + " 是100的整数");
                    }
                    num++;
                    //每一次循环,休眠10ms
                    Thread.sleep(10);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        //启动线程
        Thread thread = new Thread(runnable);
        thread.start();

        //此处的  Thread.sleep(5000); 是休眠主线程, 让子线程运行5s,
        //子线程运行5s后, 给出子线程的休眠信号
        Thread.sleep(5000);
        thread.interrupt();
    }

}

打印的结果如下. 与加上判断线程是否中断的一致.

因此, 只要子线程在while循环的过程中, 每一次循环都会有让线程进行阻塞一段时间的情况下, 就不需要加上线程是否被中断的条件判断 . 因为会在阻塞的过程中,检测中断的状态, 并且抛出异常

到此这篇关于Java多线程中停止线程遇到线程阻塞的处理方法详解的文章就介绍到这了,更多相关Java线程阻塞的处理方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • idea打开项目后无法显示目录结构,只能显示.iml文件问题

    idea打开项目后无法显示目录结构,只能显示.iml文件问题

    这篇文章主要介绍了idea打开项目后无法显示目录结构,只能显示.iml文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java如何解决发送Post请求报Stream closed问题

    Java如何解决发送Post请求报Stream closed问题

    这篇文章主要介绍了Java如何解决发送Post请求报Stream closed问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • MyBatis流式查询的三种实现方法

    MyBatis流式查询的三种实现方法

    流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果,本文介绍了MyBatis流式查询的实现,感兴趣的可以了解一下
    2021-05-05
  • SpringBoot如何访问jsp页面

    SpringBoot如何访问jsp页面

    本文介绍了如何在Spring Boot项目中进行Web开发,包括创建项目、配置文件、添加依赖、控制层修改、测试效果以及在IDEA中进行配置的详细步骤
    2025-01-01
  • Spring MVC概念+项目创建+@RequestMappring案例代码

    Spring MVC概念+项目创建+@RequestMappring案例代码

    Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet,这篇文章主要介绍了Spring MVC概念+项目创建+@RequestMappring,需要的朋友可以参考下
    2023-02-02
  • 自定义@RequestBody注解如何获取JSON数据

    自定义@RequestBody注解如何获取JSON数据

    这篇文章主要介绍了自定义@RequestBody注解如何获取JSON数据问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • list的4种遍历方式(实例讲解)

    list的4种遍历方式(实例讲解)

    下面小编就为大家带来一篇list的4种遍历方式(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Springboot-Management的项目实践

    Springboot-Management的项目实践

    本文主要介绍了Springboot-Management的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • Springboot参数校验之分组校验、嵌套校验的实现

    Springboot参数校验之分组校验、嵌套校验的实现

    日常开发中,免不了需要对请求参数进行校验,诸如判空,长度,正则,集合等,复杂一点的请求参数可能会包含嵌套,分组校验,本文就详细的介绍一下,感兴趣的可以了解一下
    2023-08-08
  • IDEA中Services栏不显示的解决方案小结

    IDEA中Services栏不显示的解决方案小结

    正常编译完一个SpringBoot或者SringCloud项目之后,Services都会显示出你有哪些服务,如果没有services栏怎么解决呢?下面小编给大家分享IDEA中Services栏不显示的解决方案小结,感兴趣的朋友一起看看吧
    2021-08-08

最新评论