2012-03-10 19 views

回答

10

是什麼的AbstractQueuedSynchronizer在concurrent.locks封裝中使用 爲

的的AbstractQueuedSynchronizer是對於那些在java.util.concurrency使用和實施(至少是)同步結構的積木包。

例如,ReentrantLock委託給擴展AbstractQueuedSynchronizer的Sync。如果你寫你自己的鎖它可能看起來像這樣

public class MyLock extends AbstractQueuedSynchronizer implements Lock{ 
    @Override 
    public void lock() { 
     super.acquire(1); 
    } 
    @Override 
    public void unlock() { 
     if(Thread.currentThread() != super.getExclusiveOwnerThread()) 
      throw new IllegalMonitorStateException(); 
     super.release(1); 
    } 
} 

所以在這裏,同時處理任何特殊功能本身(例如該鎖的MyLock類將繼承線程掛起&的低級別的功能排隊到AQS要求擁有鎖的線程是釋放它的線程,但信號量不會)。

有人可以扔在其方法的一些光doAcquireInterruptibly和 parkAndCheckInterrupt

注:這些方法都是私有的類,所以實際的功能是能夠在不同的版本或不同的實現之間切換。目前我解釋的默認提供的功能如下:

doAcquireInterruptibly將試圖成爲此同步的獨佔所有者。它會一直這樣做直到線程被中斷或成功獲取。考慮一個線程試圖輸入一個​​塊,該線程將在那裏等待,直到它進入監視器(當前沒有線程擁有線程或擁有線程存在監視器)。這樣做的好處是獲取線程可以被中斷。

parkAndCheckInterrupt只是一種方便的方法,它會暫停(停放)一個線程,並在重置中斷狀態時返回。

+0

啊!謝謝John ...很好的解釋 – Hemanshu 2012-03-10 10:49:31

+1

@ Hemanshu:如果這個答案對你有幫助,請將它標記爲已接受。這表示感謝那些幫助你的人,也是引導他人解決這個問題的一種方式。 – 2012-10-24 05:20:46

6
  • 的AbstractQueuedSynchronizer:它提供了一個框架來實現阻塞鎖和相關同步器像信號量,CountDownLatch等,爲獲得基本的算法嘗試收購,如果成功返回其他排隊的線程,如果沒有排隊和塊當前線程。同樣,基本的釋放算法是嘗試釋放,如果成功,則取消阻塞隊列中的第一個線程,否則直接返回。線程將在先進先出(FIFO)等待隊列中等待。抽象方法tryAcquire和tryRelease將根據需要由子類實現。

  • doAcquireInterruptibly將試圖獲得鎖。如果該鎖已被其他線程獲取,則當前線程將被阻塞(停放)。如果它獲得鎖定,它將簡單地返回。

  • parkAndCheckInterrupt將停止線程或換句話說禁用線程調度,直到某個其他線程解鎖它。這可能是由於擁有線程釋放了鎖或由於其他線程中斷了它。如果它被其他線程中斷,則會拋出異常。
2

我想談談AbstractQueuedSynchronizer(AQS)和一些簡單的單詞。

想想在現實世界中這些場景:

  • 對於游泳者,他們可以在游泳池(共享)一起游泳。但 清潔誰將衛生與氯思考,他必須等待 ,直到所有游泳者已經(獨家)。
  • 對於在繁忙的停車場外面是 的司機,他們必須排隊等候。通常門衛會控制訪問。一輛普通的汽車將需要一個停車位。林肯豪華轎車可能需要兩個或更多

正如我們看到的,是3個變量:

  1. 總資源量。
  2. 每次使用多少資源。
  3. 訪問策略(共享/排他)。

AQS是一個模板類,用於管理關鍵部分,這意味着您可以擴展它並填寫上面的變量以完成您的工作。有關如何避免比賽危險或控制隊列的細節已經隱藏起來。

爲了進一步閱讀,您最好了解互斥鎖,信號量和ReentrantReadWriteLock的源代碼。