如何安全地终止线程interrupt()、isInterrupted()、interrupted()的区别与使用

二、如何安全地终止线程

有2种方法可以安全地终止线程:

  1. 使用interrupt()
  2. 外部干涉(推荐)。

interrupt()、isInterrupted()、interrupted()的区别与使用


interrupt()

注意区分interrupted()方法;

public void interrupt()

interrupt()是用于中断线程的,调用该方法,线程的状态将被置为"中断"状态
注意:线程中断仅仅是设置线程的中断状态位,++不会停止线程++。需要用户自己去监视线程的状态为并做处理。


isInterrupted()

isInterrupted()测试线程是否已经中断。线程的 中断状态 不受该方法的影响

public boolean isInterrupted()

interrupted()

public static boolean interrupted()

interrupted()第一次使用返回true,并清除中断标志位,在此之后查询中断状态isInterrupt()都会返回false,第一次返回的true可以跳出循环。第二次以及以后都是返回false。


区别案例

public class InterruptExample {

    private static class MyThread extends Thread {
        @Override
        public void run() {
            while (true) {
                System.out.println(isInterrupted());
                
                //interrupt()并不会中断线程,所以后面的代码会被继续执行;
                interrupt();
                System.out.println(isInterrupted());
                
                //interrupted()第一次返回true,并清除标志位,所以以后查询中断状态返回的都是false
                System.out.println(interrupted());
                System.out.println(isInterrupted()); //false
                break;
            }
            System.out.println("Thread end");
        }
    }

    public static void main(String[] args){
        Thread thread = new MyThread2();
        thread.start();
    }
}

输出

false
true
true   //interrupted()第一次返回true
false
Thread end

注意

  1. 通过调用一个线程的 interrupt()来中断该线程,如果该线程处于阻塞限期等待或者无限期等待状态,那么就会抛出 InterruptedException,从而提前结束该线程。但是不能中断 I/O 阻塞和 synchronized 锁阻塞。

  2. suspend()、resume()和stop()过期了,不建议使用;

public class InterruptExample {

    private static class MyThread1 extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(2000);
                System.out.println("Thread run");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public static void main(String[] args) throws InterruptedException {
    Thread thread1 = new MyThread1();
    thread1.start();
    thread1.interrupt();
    System.out.println("Main run");
}

由于线程中调用了Thread.sleep()方法,因此会抛出一个 InterruptedException,从而提前结束线程,不执行之后的语句。

Main run
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at InterruptExample.lambda$main$0(InterruptExample.java:5)
    at InterruptExample$$Lambda$1/713338599.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

使用interrupt()方法终止线程

public class InterruptExample {

    private static class MyThread2 extends Thread {
        @Override
        public void run() {
        //
            while (!isInterrupted()) {
                // ..
            }
            System.out.println("Thread end");
        }
    }
}
public static void main(String[] args) throws InterruptedException {
    Thread thread2 = new MyThread2();
    thread2.start();
    thread2.interrupt();
}
Thread end

外部干涉

public class InterruptExample {

    private static class MyThread extends Thread {
        private volatile boolean on = true;
        @Override
        public void run() {
            while (on) {
                //todo
            }
        }
        public void cancel(){
            on = false;
        }
    }


    public static void main(String[] args) {
        Thread thread = new MyThread();
        thread.start();
        thread.cancel();
    }
}

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页