检测中断状态的方法一般是: 循环检测(猜测native方法wait、unsafe的park等方法也是用循环检测);
对于一个线程 t, 其他线程只能改变其中断状态,系统(线程调度器)检测其中断状态,若被中断则将其唤醒(在阻塞的IO中不唤醒),然后由t检测自己的中断标志并抛出中断异常;
如果t不检查或检查中断而决定不抛出异常,也就是不搭理其他线程的信号,那么t就会像被正常唤醒一样,不过这会破坏系统的锁机制(同步与互斥),所以线程模型都是有系统和框架实现好的,规定其醒来后首先检测中断标志,若是因为被中断而唤醒,则释放资源(比如已经获得的锁,依框架机制而定)并抛出中断异常。
// ReentrantLock.java abstract static class Sync extends AbstractQueuedSynchronizer{ ... } static final class NonfairSync extends Sync { ... } static final class FairSync extends Sync { ... } public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); }
检测中断状态的方法一般是: 循环检测(猜测native方法wait、unsafe的park等方法也是用循环检测)
AbstractQueuedSynchronizer.java:
public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg); }
AbstractQueuedSynchronizer.java:
private final boolean parkAndCheckInterrupt() { LockSupport.park(this); return Thread.interrupted(); }
LockSupport的park 可能使当前线程(称其为T)阻塞。当线程T阻塞时,如果其interrupt被调用,则park方法返回,但是park并不抛出InterruptedException, 即不改变T的中断状态,所以需要重新检查T的状态,正如上面的parkAndCheckInterrupt方法所做的一样。注意Thread.interrupted() 方法会返回并清楚当前的中断状态。