Lock 與 InterruptedException

檢測中斷狀態的方法通常是: 循環檢測(猜想native方法wait、unsafe的park等方法也是用循環檢測); java

對於一個線程 t, 其餘線程只能改變其中斷狀態,系統(線程調度器)檢測其中斷狀態,若被中斷則將其喚醒(在阻塞的IO中不喚醒),而後由t檢測本身的中斷標誌並拋出中斷異常;框架

若是t不檢查或檢查中斷而決定不拋出異常,也就是不搭理其餘線程的信號,那麼t就會像被正常喚醒同樣,不過這會破壞系統的鎖機制(同步與互斥),因此線程模型都是有系統和框架實現好的,規定其醒來後首先檢測中斷標誌,如果由於被中斷而喚醒,則釋放資源(好比已經得到的鎖,依框架機制而定)並拋出中斷異常。ui


// 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等方法也是用循環檢測)this


AbstractQueuedSynchronizer.java:spa

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() 方法會返回並清楚當前的中斷狀態。code

相關文章
相關標籤/搜索