久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

快速過一下并發(fā)的基礎類AbstractQueuedSynchronizer源碼

 IT樂知 2020-07-24

AbstractQueuedSynchronizer是并發(fā)的一個關鍵基礎類,,它是很多并發(fā)類的構成基礎,比如ReentrantLock,、CountDownLatch等,,了解了它其他類就簡單明了了,。

基礎結構

AbstractQueuedSynchronizer(后面簡稱AQS)繼承AbstractOwnableSynchronizer類,AbstractOwnableSynchronizer類只有一個屬性“private transient Thread exclusiveOwnerThread;”以及他的get\set方法,,可以用來表示當前獨占鎖持有的線程,。

AQS是一個抽象類,并且構造方法是protected的,,所以只能繼承使用,。

AQS包含一個int型的state和一個鏈表,state用來表示資源狀態(tài),,比如ReentrantLock用state的0,、1來表示鎖是否已經被獲取,鏈表用來保存阻塞的線程,。所以AQS有三個屬性state,、head(鏈表的頭節(jié)點)、tail(鏈表的尾節(jié)點),。

鏈表結構是一個AQS的內部類Node,Node類包含屬性有:

waitStatus:狀態(tài),,取消(取消獲取鎖),掛起(表示包含的線程正在掛起狀態(tài)),,等待等狀態(tài),;

prev:節(jié)點的前一個節(jié)點;

next:節(jié)點后一個節(jié)點

thread:節(jié)點對應阻塞的線程,,

nextWaiter:用來表示節(jié)點類型,,是獨占鎖還是共享鎖;

基礎方法

AQS有三個final的基礎方法getState() ,、setState(int newState) ,、 compareAndSetState(int expect, int update) ,由于state是用volatile修飾的,,所以簡單的get\set方法也能得到正確的結果,,然后compareAndSetState方法是采用cas方式修改state。

需重寫方法

AQS還定義了5個需要子類去重寫的方法,,方法內部并沒有實現(xiàn)任何代碼,,而是直接拋出UnsupportedOperationException異常,這5個方法為 tryAcquire(int arg),、tryRelease(int arg),、tryAcquireShared(int arg)、tryReleaseShared(int arg),、 isHeldExclusively(),根據(jù)名字能夠猜到大概意思是獲取鎖,、釋放鎖等功能,。
AQS定義了這個幾個方法主要是讓各自的實現(xiàn)類根據(jù)各自的情況來管理state,,比如ReentrantLock中的實現(xiàn)類的tryAcquire方法就是嘗試把state的只設置為1,Semaphor中實現(xiàn)的tryAcquireShared則是嘗試把state減少一定的數(shù)量,。不同的實現(xiàn)類實現(xiàn)不同的就能實現(xiàn)不同的阻塞,,比如ReentrantLock中state為1表示鎖已被獲取,Semaphor中state小于0表示信號量已用盡,,所以這些實現(xiàn)都是把state當成資源,,一旦state達到某種狀態(tài),表示資源耗盡,,一般都會阻塞線程,。

已實現(xiàn)的模板方法

模板方法是AQS中對外的最關鍵的方法,是擴展其他功能的基礎方法,,方法提供的最主要的功能就是獲取資源或阻塞線程,,釋放資源喚醒線程,主要幾個方法如下:
acquire(int arg) :先調用tryAcquire方法嘗試獲取資源,,如果失敗通過acquireQueued方法阻塞線程同時生成一個節(jié)點并設置進鏈表的尾部,。
acquireInterruptibly(int arg):與上一個功能類似,在獲取資源的過程中會多次判斷線程是否中斷,,如果中斷則拋出中斷異常,。
tryAcquireNanos(int arg, long nanosTimeout):一定時間內沒有獲取到就不會再獲取了。
release(int arg):會調用tryRelease成功后,,會喚醒后面節(jié)點中的線程,;
acquireShared(int arg):調用tryAcquireShared獲取共享資源,如果失敗會阻塞線程并創(chuàng)建一個共享節(jié)點加入到鏈表中,;
acquireSharedInterruptibly(int arg):與上一個方法相似,,不過在獲取資源與排隊的過程中會校驗線程的中斷狀態(tài),如果線程狀態(tài)會中斷則會直接拋出異常,;
tryAcquireSharedNanos(int arg, long nanosTimeout):一定時間內沒有獲取到共享鎖則失?。?/span>
releaseShared(int arg):先釋放資源,,在喚醒隊列后面的節(jié)點中的線程,;
   這幾個方法都是結合上一節(jié)中需重寫的方法執(zhí)行的結果來進行下一步操作,比如acquire方法會先調用tryAcquire方法,,如果tryAcquire返回true則直接成功,,返回false表示獲取資源失敗,接著就會調用AQS私有方法acquireQueued將線程阻塞并且加到鏈表中去,。這幾個方法都是差不多采用這種方式,。
  通過這種方式由繼承類來實現(xiàn)對state的管理,由AQS來管理阻塞線程隊列,,這樣不同的實現(xiàn)類可以實現(xiàn)不同的功能,,同時又不用實現(xiàn)管阻塞線程,、喚醒線程、線程隊列等其他復雜的功能,,而只用對state控制就行,。
截取了其中兩個方法的源碼如下圖:
1源碼

不太重要的功能

hasQueuedThreads():是否有阻塞線程;
hasContended():head != null用來判斷是否有線程阻塞過,。
getFirstQueuedThread():獲取最前面的線程,,
isQueued(Thread thread):用來判斷線程是否在阻塞隊列中
apparentlyFirstQueuedIsExclusive():判斷最前面的節(jié)點是不是獨占。
hasQueuedPredecessors():判斷當前線程前面是否還有線程在阻塞中

總結

AQS通過一個int型的state來表示資源,,再用一個鏈表來存放阻塞的線程,,AQS來管理鏈表、阻塞線程,、喚醒線程,,由子類來實現(xiàn)對state的修改和判斷。在前面中沒有說對值得修改與線程的阻塞,、喚醒都是通過Unsafe這個類,,這個類中都是本地方法。

AQS實際上就是封裝了對線程的一系列操作,,在這個基礎上要實現(xiàn)其他功能就比較簡單了,,后面閱讀ReentrantLock和Semaphor等源碼就會發(fā)現(xiàn)是多么的簡單了。

Java程序員日常學習筆記,,如理解有誤歡迎各位交流討論,!

    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多