【多线程】线程的中断机制与处理

39 阅读2分钟

interrupt方法是Thread类中的一个方法,用于向目标线程发送一个中断请求。它是一种协作式的机制,用于通知目标线程应该在合适的时候停止当前的操作。

比如存在一个长时间运行的文件下载线程,当用户想要取消下载时,可以在主线程中调用下载线程的interrupt方法来请求中断该线程。

相关变量和方法

Thread中有一个中断标志位(默认是false),可以通过调用Thread.isInterrupted()方法来获取他的值。

通过调用Thread.interrupt()方法设置当前线程的中断标志。

通过调用Thread.interrupted()方法可以检查中断标志并清除中断状态(这个方法会返回当前中断标志的状态并将中断标志重置为false)。

如何处理中断

线程发生中断的情景有两种,主动中断和被动中断。

先看被动中断

在阻塞方法(如Thread.sleep()Object.wait()等)中,如果线程被中断,这些方法会抛出InterruptedException异常,这个异常的抛出是为了通知等待的线程,它的等待状态被外部因素(另一个线程的中断操作)所干扰。在捕获这个异常时,可以进行相应的中断处理。

Thread thread = new Thread(() -> {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        System.out.println("线程被中断,从睡眠中唤醒");
    }
});
thread.start();
thread.interrupt();

当一个阻塞方法(如wait)抛出InterruptedException时,它会自动清除线程的中断状态。(意味着中断标志位还是false)

但是,在某些情况下,更高层次的代码可能需要知道这个线程被中断了。

被动中断捕抓异常时,可以重新设置线程的中断状态。这就是线程主动设置中断

这个时候的代码可以这样写

try { 
    lock.wait(); 
} catch (InterruptedException e) { 
    Thread.currentThread().interrupt(); 
}

重新设置线程的中断状态,让更高层次的代码可以感受到线程被中断了。