线程中断机制

193 阅读2分钟

Java线程中断是一种协作机制,设置线程的中断标志并不能直接终止该线程执行,而是被中断的线程根据中断状态自行处理。

API核心方法

实例方法interrupt

public void interrupt() {
    //...
}
  1. main线程调用t.interrupt()方法,将线程t的中断标志位设置为true,线程t还会继续执行
  2. 线程t调用了wait/sleep/join方法被阻塞后,main线程调用t.interrupt()方法时,线程t会在阻塞处抛InterruptedException异常。可在抛异常处继续中断当前线程,便于t1线程根据中断状态自行处理
Thread t1 = new Thread(()->{
    while (true) {
        if(Thread.currentThread().isInterrupted()) {
            System.out.println("t1线程被中断了, 程序结束!");
            break;
        }

        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println(Thread.currentThread().getName() + " 被中断了");
        }

        System.out.println("----------hello");
    }
}, "t1");
t1.start();
System.out.println("--------------" + t1.isInterrupted());
//休眠5毫秒
TimeUnit.MILLISECONDS.sleep(5);
t1.interrupt();
System.out.println("--------------" + t1.isInterrupted());

执行结果:
--------------false
--------------true
t1 被中断了
----------hello
t1线程被中断了, 程序结束!

实例方法isInterrupted

public boolean isInterrupted() {
    return isInterrupted(false);//传递false,说明不清除中断标志
}

判断当前线程是否被中断

静态方法interrupted

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

检测当前线程是否中断。如果当前线程被中断,会清除中断标志位。

Thread t = new Thread(()->{
   while (true){}
});

t.start();
t.interrupt();

System.out.println(t.isInterrupted()); 
System.out.println(t.interrupted());//获取当前线程的中断标志,当前线程是main线程    
System.out.println(Thread.interrupted());//获取当前线程的中断标志,当前线程是main线程 
System.out.println(t.isInterrupted());

执行结果:
true
false
false
true

应用实例

  1. 比如一个线程t调用Thread.sleep(3000),线程t会阻塞,要等到3秒后才能变为就绪状态,此时可以使用t.interrupt()方法,强制sleep方法抛出InterruptedException异常并返回,线程t就恢复到就绪状态。
Thread t = new Thread(()->{
    System.out.println("run....");

    try {
        TimeUnit.SECONDS.sleep(10);
    } catch (InterruptedException e) {
        System.out.println("main线程中断了t线程");
    }
    System.out.println("阻塞后开始执行。。。");
});

t.start();

try {
    TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
    e.printStackTrace();
}
t.interrupt();
结果分析:
run....
main线程中断了t线程
阻塞后开始执行。。。

思考

  1. 有哪些方法会抛InterruptedException异常 wait/join/sleep