zoukankan      html  css  js  c++  java
  • 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()方法由于中断而抛出异常,此时,它会清除中断标记,如果不加以处理,那么下一次循环开始时,就无法捕获这个中断,故在异常处理中,再次设置中断标记位

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

    未被中断
    睡眠时发生了中断异常
    未被中断
    未被中断
    未被中断
    未被中断
    .......
    ...
    .
  • 相关阅读:
    一本通1018
    并查集&MST
    hdu 1875 畅通工程再续
    hdu 1811 Rank of Tetris(拓扑排序+并查集)
    hdu 1325 is it a tree?
    hdu1285拓扑排序
    hdu2063 过山车(最大二分匹配)
    最小生成树二·Kruscal算法
    hiho一下 第二十一周(线段树 离散化)
    hiho一下 第二十周(线段树模板)
  • 原文地址:https://www.cnblogs.com/java-spring/p/8315407.html
Copyright © 2011-2022 走看看