java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java线程阻塞的处理方法

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

作者: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线程阻塞的处理方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文