摘要:線程將再次嘗試獲取鎖定以確保它在實(shí)際停放之前無法獲取。如果沒有頭,則表示隊(duì)列中沒有線程,因此沒有人發(fā)出信號。如果后繼節(jié)點(diǎn)未處于取消狀態(tài),則取消后繼節(jié)點(diǎn)的線程,以便它可以重試獲取。
摘要排隊(duì)同步器類
它提供了一個框架,用于實(shí)現(xiàn)阻塞鎖和相關(guān)的同步器,如信號量, CountDownLatch等。獲取的基本算法是try acquire,如果成功則返回其他排隊(duì)線程(如果它尚未排隊(duì))并阻止當(dāng)前線程。同樣,發(fā)布的基本算法是try release,如果成功,則取消阻塞隊(duì)列中的第一個線程,否則只返回。線程將在先進(jìn)先出(FIFO)等待隊(duì)列中等待。抽象方法 tryAcquire()和tryRelease()將根據(jù)需要由子類實(shí)現(xiàn)。
以獨(dú)家模式獲取
以獨(dú)占模式獲取的通用算法
AbstractQueuedSynchronizer(AQS)
在上面的圖中"shouldParkAfterFailedAcquire?" 驗(yàn)證前任的等待狀態(tài)是否為SIGNAL。如果是,它確定前任線程將在其釋放時SIGNAL,因此它將立即阻止,否則它可能會重試獲取鎖,以防它是隊(duì)列中的第一個節(jié)點(diǎn)。
AbstractQueuedSynchronizer(AQS)
隊(duì)列
如果線程無法獲取鎖,它將被放入隊(duì)列中。如果隊(duì)列尚不存在,它將使用虛擬標(biāo)頭初始化它,然后將其自身鏈接到它。頭部的“下一個”和節(jié)點(diǎn)的“上一個”將被鏈接。新節(jié)點(diǎn)也成了尾巴。標(biāo)題節(jié)點(diǎn)的等待狀態(tài)將設(shè)置為SIGNAL,以便當(dāng)所有者線程釋放鎖時,它可以通知頭節(jié)點(diǎn)的后繼者獲取鎖。線程將再次嘗試獲取鎖定以確保它在實(shí)際停放之前無法獲取。
AbstractQueuedSynchronizer(AQS)
因此,只要其前任節(jié)點(diǎn)的等待狀態(tài)被設(shè)置為SIGNAL,就可以安全地停放未能獲得鎖的線程,因此一旦前一個被釋放,它就可以重試獲取鎖。
如果前一個被取消,它將跳過所有被取消的前任,以重置其等待線程的next和prev指針。
AbstractQueuedSynchronizer(AQS)
發(fā)布
AbstractQueuedSynchronizer(AQS)
子類將根據(jù)他們的要求實(shí)現(xiàn)“try Release”。一旦發(fā)布,標(biāo)頭節(jié)點(diǎn)的后繼節(jié)點(diǎn)需要發(fā)信號,以便它可以重新嘗試獲取。如果沒有頭,則表示隊(duì)列中沒有線程,因此沒有人發(fā)出信號。如果磁頭存在,則確保等待狀態(tài)不為零。如果它為零,則意味著不需要發(fā)信號通知后繼節(jié)點(diǎn)。
Unpark后繼節(jié)點(diǎn)的線程
線程到unpark是在后繼節(jié)點(diǎn),通常只是下一個節(jié)點(diǎn)。
情況1:如果頭部的等待狀態(tài)<0,則清除等待狀態(tài)。如果后繼節(jié)點(diǎn)(P1)未處于取消狀態(tài),則取消后繼節(jié)點(diǎn)的線程,以便它可以重試獲取。
AbstractQueuedSynchronizer(AQS)
情況2:如果后繼節(jié)點(diǎn)取消或?yàn)閚ull,則從尾部向后遍歷以查找實(shí)際未取消的后繼節(jié)點(diǎn)。
AbstractQueuedSynchronizer(AQS)
一旦取消停放線程,其節(jié)點(diǎn)就成了新頭。老頭將脫鉤。如果未能獲得,將重新停放。頭節(jié)點(diǎn)的等待狀態(tài)設(shè)置為0將重置為SIGNAL。
發(fā)布共享
這與獨(dú)家發(fā)布類似。它還確保釋放傳播。
以共享模式獲取
這類似于獨(dú)家收購。它還將釋放傳播到隊(duì)列中等待獲取共享鎖的其他等待線程。一旦鎖定被釋放,它就會取消其后繼節(jié)點(diǎn)的停放,后者又將釋放傳播到下一個節(jié)點(diǎn)。
取消
在嘗試獲取時可能存在運(yùn)行時異常,在這種情況下將取消上下文中的節(jié)點(diǎn)。如果節(jié)點(diǎn)被取消,我們必須確保其后繼節(jié)點(diǎn)正確鏈接到有效的前任節(jié)點(diǎn),因此可能必須調(diào)整鏈接。如果其前任節(jié)點(diǎn)已經(jīng)處于取消狀態(tài),則將跳過這些節(jié)點(diǎn)以到達(dá)具有等待狀態(tài)<= 0的適當(dāng)?shù)那叭喂?jié)點(diǎn)。
如果要取消的節(jié)點(diǎn)本身是尾節(jié)點(diǎn),則將簡單地將其移除。它的前身節(jié)點(diǎn)將成為新的尾巴。新尾部的“下一個”鏈接將指向null。
如果等待狀態(tài)<0,則表示后繼者需要信號,嘗試設(shè)置前任的下一個鏈接,以便獲得一個。如果前任是頭節(jié)點(diǎn)本身,則它將喚醒其后繼節(jié)點(diǎn)。
情況1:要取消的節(jié)點(diǎn)是尾節(jié)點(diǎn)
AbstractQueuedSynchronizer(AQS)
情況2:取消節(jié)點(diǎn)的前任是head,現(xiàn)在將發(fā)信號通知被取消節(jié)點(diǎn)的下一個節(jié)點(diǎn)被喚醒。
原文地址:https://www.javarticles.com/2...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/75352.html
摘要:線程將再次嘗試獲取鎖定以確保它在實(shí)際停放之前無法獲取。如果沒有頭,則表示隊(duì)列中沒有線程,因此沒有人發(fā)出信號。如果后繼節(jié)點(diǎn)未處于取消狀態(tài),則取消后繼節(jié)點(diǎn)的線程,以便它可以重試獲取。 摘要排隊(duì)同步器類它提供了一個框架,用于實(shí)現(xiàn)阻塞鎖和相關(guān)的同步器,如信號量, CountDownLatch等。獲取的基本算法是try acquire,如果成功則返回其他排隊(duì)線程(如果它尚未排隊(duì))并阻止當(dāng)前線...
摘要:總結(jié)總的來說,操作順序是進(jìn)入隊(duì)列喚醒,成功獲得鎖將狀態(tài)變?yōu)椴⑵鋸霓D(zhuǎn)到使再次獲得鎖執(zhí)行余下代碼。當(dāng)然這是理由狀態(tài)下,為了討論及的原理,實(shí)際的操作時序也有可能變化。 AQS Condition 最近面試被問到j(luò)ava concurrent包下有哪些熟悉的,用過的工具。因此來回顧一下,這些工具的底層實(shí)現(xiàn),AbstractQueuedSynchronizer。在網(wǎng)上看到了其他人的一些技術(shù)博客...
摘要:總結(jié)總的來說,操作順序是進(jìn)入隊(duì)列喚醒,成功獲得鎖將狀態(tài)變?yōu)椴⑵鋸霓D(zhuǎn)到使再次獲得鎖執(zhí)行余下代碼。當(dāng)然這是理由狀態(tài)下,為了討論及的原理,實(shí)際的操作時序也有可能變化。 AQS Condition 最近面試被問到j(luò)ava concurrent包下有哪些熟悉的,用過的工具。因此來回顧一下,這些工具的底層實(shí)現(xiàn),AbstractQueuedSynchronizer。在網(wǎng)上看到了其他人的一些技術(shù)博客...
摘要:如果此時,鎖被釋放,需要通知等待線程再次嘗試獲取鎖,公平鎖會讓最先進(jìn)入隊(duì)列的線程獲得鎖。等待隊(duì)列節(jié)點(diǎn)的操作由于進(jìn)入阻塞狀態(tài)的操作會降低執(zhí)行效率,所以,會盡力避免試圖獲取獨(dú)占性變量的線程進(jìn)入阻塞狀態(tài)。 ?今天我們來研究學(xué)習(xí)一下AbstractQueuedSynchronizer類的相關(guān)原理,java.util.concurrent包中很多類都依賴于這個類所提供隊(duì)列式同步器,比如說常用的R...
閱讀 1876·2021-09-24 09:48
閱讀 3220·2021-08-26 14:14
閱讀 1674·2021-08-20 09:36
閱讀 1460·2019-08-30 15:55
閱讀 3627·2019-08-26 17:15
閱讀 1425·2019-08-26 12:09
閱讀 606·2019-08-26 11:59
閱讀 3323·2019-08-26 11:57