【并发编程】-- 线程的interrupt()方法实现原理

89 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情

线程的interrupt()方法

使用interrupt方法可以中断线程,除非始终允许当前线程中断本身,否则该线程会调用checkAccess方法,这可能会导致抛出SecurityException异常。

  • 如果线程在调用wait()、wait(long)、wait(long,int)、join()、join(long)、join(long、int)、sleep(long)、sleep(long,int)方法时被阻塞,那么该线程的中断标志位将会被清除并且会收到一个InterruptedException异常。
  • 如果线程在InterruptibleChannel上执行IO操作时被阻塞,这个通道将会被关闭,线程中断标志位将会被重置,且会收到一个ClosedByInterruptException异常。
  • 如果线程是在Selector上被阻塞,那么线程的中断标志位将会被重置,并且会立即从选择操作中返回,可能是非0值,就像调用Selector.wakeup方法一样。
  • 如果以上情况均不满足,线程中断标志位会被重置。中断未激活的线程不会产生任何效果。
public void interrupt(){
    if(this != Thread.currentThread()){
        checkAccess();
        synchronized(blockerLock){
            Interruptible blo=blocker;
            if(blo != null){
                interrupt();
                blo.interrupt(this);
                return ;
            }
        }
        interrupt0();
    }
    
public static boolean interrupted(){
    return currentThread().isInterrupted(true);
}
   
public boolean isInterrupted(){
    return isInterrupted(false);
}
}

private native boolean isInterrupted(boolean ClearInterrupted);

注意点:

interrupted()方法用于测试当前线程是否已经中断,该线程的中断标志位已经被清除,如果isInterrupted()方法被成功调用两次,那么第2次调用将会返回false,除非在第一次调用已经清除了中断标志位之后,第二次调用检查之前,当前线程再次中断,由于线程在中断时未被激活而忽视,因此该方法会返回false。

isInterrupted()方法用于测试线程是否已经中断,线程的中断标志位不会受此方法影响;由于线程在中断时未被激活而忽视,因此该方法会返回false。

isInterrupted(boolean ClearInterrupted)方法用于测试线程是否中断,根据传递的ClearInterrupted值决定中断标志位值重置或者不重置。