Lock 与 InterruptedException

检测中断状态的方法一般是: 循环检测(猜测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:

Lock 与 InterruptedException

Lock 与 InterruptedException

Lock 与 InterruptedException

Lock 与 InterruptedException

private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
    }


LockSupport的park 可能使当前线程(称其为T)阻塞。当线程T阻塞时,如果其interrupt被调用,则park方法返回,但是park并不抛出InterruptedException, 即不改变T的中断状态,所以需要重新检查T的状态,正如上面的parkAndCheckInterrupt方法所做的一样。注意Thread.interrupted() 方法会返回并清楚当前的中断状态。

Lock 与 InterruptedException

你可能感兴趣的:(Lock 与 InterruptedException)