• Interrupt中断线程注意点


    首先我们要明确,线程中断并不会使线程立即退出,而是发送一个通知,告知目标线程你该退出了,但是后面如何处理,则完全有目标线程自行决定。

    这就是和stop()不一样的地方,stop执行后线程会立即终止,这样可能会引起数据不一致的问题(所以stop()方法已经被废弃不推荐使用了)。

    线程中断有三个方法

    public void Thread.interrupt();    //中断线程,设置中断标志位
    public void Thread.isInterrupted();    //判断是否被中断
    public void Thread.interrupted();    //判断是否被中断,并清除当前中断状态

    先看下面一段代码

    public class InterruptThread {
    
        public static void main(String[] args) throws Exception {
            Thread thread = new Thread() {
                public void run() {
                    while (true) {
                        Thread.yield();
                    }
                }
            };
            thread.start();
            Thread.sleep(2000);
            thread.interrupt();// 设置中断标志位
        }
    }

    虽然对thread进行了中断,但是thread并没有中断处理逻辑,所以这个中断就不起作用,否则,中断就和stop没什么两样了。

    再看下面的代码

    package com.thread.test;
    
    public class InterruptThread {
    
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread() {
                public void run() {
                    while (true) {
                        //Thread.currentThread().isInterrupted();检查中断标志位--检查线程是否有被中断
                        if (Thread.currentThread().isInterrupted()) {
                            System.out.println("被中断了");
                            break;
                        }
                        Thread.yield();
                    }
                };
            };
            thread.start();
            Thread.sleep(2000);
            thread.interrupt();//设置中断标志位
        }
    
    }
    isInterrupted()用于判断线程是否被中断,如果被中断则退出循环体。
    请注意,代码中sleep()方法总会抛出一个
    InterruptedException中断异常,它不是运行时异常,因此我们必须捕获它并处理,当线程在睡眠的时候如果被中断,这个异常就会产生
    请看以下代码
    package com.thread.test;
    
    public class InterruptThread {
    
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread() {
                public void run() {
                    while (true) {
                        System.out.println("未被中断");
                        //Thread.currentThread().isInterrupted();检查中断标志位--检查线程是否有被中断
                        if (Thread.currentThread().isInterrupted()) {
                            System.out.println("被中断了");
                            break;
                        }
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            System.err.println("睡眠时发生了中断异常");
                            Thread.currentThread().interrupt();//设置中断标志位
                        }
                        Thread.yield();
                    }
                };
            };
            thread.start();
            Thread.sleep(2000);
            thread.interrupt();//设置中断标志位
        }
    
    }

    运行后输出结果为:

    未被中断
    睡眠时发生了中断异常
    未被中断
    被中断了

    注意:sleep()方法由于中断而抛出异常,此时,它会清除中断标记,如果不加以处理,那么下一次循环开始时,就无法捕获这个中断,故在异常处理中,再次设置中断标记位

    如果不再次设置,则会输出如下结果:

    未被中断
    睡眠时发生了中断异常
    未被中断
    未被中断
    未被中断
    未被中断
    .......
    ...
    .
  • 相关阅读:
    php中字符与字节的区别
    sql把两值之和当作条件进行查询
    Intel® Neural Compute Stick 2
    使用OpenCV的VideoCapture 读取.mp4文件时出现以下错误:Unable to stop the stream: Inappropriate ioctl for device
    更换Raspbian Buster源
    OpenCV之cv2函数 2
    OpenCV中cv2的用法
    OpenVINO 对象识别 real_time_object_detection Movidius
    树莓派和计算棒实现图形识别 RaspBerry Pi4 with OpenVino and Movidius
    树莓派无线网卡老是掉线
  • 原文地址:https://www.cnblogs.com/java-spring/p/8315407.html
Copyright © 2020-2023  润新知