AbstractQueuedSynchronizer內部類Node使用講解
Node類源碼
以下是Node類源碼,同時附上了代碼解釋:
static final class Node { /** 用于表示節(jié)點正在以共享模式等待的標記 */ static final Node SHARED = new Node(); /** 用于表示節(jié)點正在以獨占模式等待的標記 */ static final Node EXCLUSIVE = null; /** waitStatus的值,表示線程已被取消 */ static final int CANCELLED = 1; /** waitStatus的值,表示后繼節(jié)點的線程需要被喚醒 */ static final int SIGNAL = -1; /** waitStatus的值,表示線程正在等待條件 */ static final int CONDITION = -2; /** * waitStatus的值,表示下一個acquireShared操作應該無條件地傳播 */ static final int PROPAGATE = -3; /** * 狀態(tài)字段,只有以下幾個取值: * SIGNAL: 后繼節(jié)點的線程被阻塞(通過park方法),因此當前節(jié)點在釋放或取消時必須喚醒其后繼節(jié)點。 * 為了避免競爭條件,acquire方法必須首先表明它們需要一個信號,然后重試原子性的acquire操作, * 失敗后再阻塞。 * CANCELLED: 由于超時或中斷,該節(jié)點被取消。節(jié)點一旦進入這個狀態(tài)就不會再離開。 * 特別地,被取消的線程不會再次阻塞。 * CONDITION: 該節(jié)點當前在條件隊列中。在轉移時,它將不再用作同步隊列節(jié)點, * 此時狀態(tài)將被設置為0。(在這里使用該值與字段的其他用途無關,但簡化了機制。) * PROPAGATE: 需要將releaseShared操作傳播到其他節(jié)點。這個值(僅用于頭節(jié)點)在doReleaseShared中設置, * 以確保傳播繼續(xù),即使在此期間有其他操作進行。 * 0: 無上述狀態(tài) * * 這些值按照數(shù)值順序排列,以簡化使用。非負值表示節(jié)點不需要發(fā)出信號。 * 因此,大多數(shù)代碼不需要檢查特定的值,只需要檢查符號即可。 * * 對于普通的同步節(jié)點,該字段初始化為0;對于條件節(jié)點,初始化為CONDITION。 * 該字段使用CAS(或在可能的情況下,無條件的volatile寫操作)進行修改。 */ volatile int waitStatus; /** * 前驅節(jié)點的鏈接,當前節(jié)點/線程依賴于它來檢查waitStatus。 * 在入隊時分配,并在出隊時置空(為了進行垃圾回收)。 * 當前驅節(jié)點被取消時,我們會快速找到一個非取消的前驅節(jié)點, * 因為頭節(jié)點永遠不會被取消:只有成功獲取鎖的結果才會成為頭節(jié)點。 * 取消的線程永遠不會成功獲取鎖,而且只有線程自己可以取消,而不是其他節(jié)點。 */ volatile Node prev; /** * 后繼節(jié)點的鏈接,在釋放時當前節(jié)點/線程將其喚醒。 * 在入隊時進行調整以跳過已取消的前驅節(jié)點,并在出隊時置空(為了進行垃圾回收)。 * 在enq操作中,直到附加之后才給前驅節(jié)點的next字段賦值, * 因此看到一個空的next字段并不一定意味著節(jié)點在隊列末尾。 * 但是,如果next字段看起來為空,我們可以從尾部向前掃描prev節(jié)點來進行雙重檢查。 * 取消的節(jié)點的next字段被設置為指向節(jié)點自身,而不是null, * 這樣可以簡化isOnSyncQueue方法的實現(xiàn)。 */ volatile Node next; /** * 入隊該節(jié)點的線程。在構造時初始化,并在使用后置空。 */ volatile Thread thread; /** * 鏈接到下一個在條件上等待的節(jié)點,或者特殊值SHARED。 * 因為條件隊列只有在持有獨占模式時才會訪問, * 所以我們只需要一個簡單的鏈式隊列來保存節(jié)點, * 而它們在等待條件時會被轉移到同步隊列中以重新獲取鎖。 * 由于條件只能是獨占的,所以我們通過使用特殊值來表示共享模式來節(jié)省一個字段。 */ Node nextWaiter; /** * 如果節(jié)點在共享模式下等待,則返回true。 */ final boolean isShared() { return nextWaiter == SHARED; } /** * 返回前驅節(jié)點,如果前驅節(jié)點為null,則拋出NullPointerException異常。 * 當無法為null時使用,可以省略空檢查,但為了幫助虛擬機,這里進行了空檢查。 * * @return 當前節(jié)點的前驅節(jié)點 */ final Node predecessor() throws NullPointerException { Node p = prev; if (p == null) throw new NullPointerException(); else return p; } Node() { // 用于建立初始頭節(jié)點或SHARED標記 } Node(Thread thread, Node mode) { // 由addWaiter方法使用 this.nextWaiter = mode; this.thread = thread; } Node(Thread thread, int waitStatus) { // 由Condition使用 this.waitStatus = waitStatus; this.thread = thread; } }
這段代碼定義了一個內部類Node
,用于構建同步隊列或條件隊列等數(shù)據(jù)結構。
代碼解釋
Node
類有一些靜態(tài)常量,如SHARED
和EXCLUSIVE
,它們分別表示共享模式和獨占模式的節(jié)點。這些常量用于區(qū)分不同類型的節(jié)點。Node
類有一個waitStatus
字段,用于表示節(jié)點的等待狀態(tài)。具體的狀態(tài)值有CANCELLED
、SIGNAL
、CONDITION
、PROPAGATE
和0,分別表示節(jié)點被取消、后繼節(jié)點需要喚醒、節(jié)點在條件隊列中等待、需要傳播信號以及無特殊狀態(tài)。這些狀態(tài)用于控制線程的等待和喚醒。Node
類有一個prev
字段和一個next
字段,分別表示前驅節(jié)點和后繼節(jié)點。這些字段用于構建隊列結構,并且在節(jié)點入隊和出隊時進行相應的調整。Node
類有一個thread
字段,表示當前節(jié)點對應的線程。Node
類有一個nextWaiter
字段,用于在條件隊列中表示下一個等待的節(jié)點,或者用SHARED
特殊值表示共享模式。isShared()
方法返回一個布爾值,表示節(jié)點是否在共享模式下等待。predecessor()
方法返回前驅節(jié)點,如果前驅節(jié)點為null
,則拋出NullPointerException
異常。Node
類有多個構造函數(shù),用于創(chuàng)建不同類型的節(jié)點。其中,一個構造函數(shù)用于addWaiter
方法,另一個構造函數(shù)用于Condition
。
總結
這段代碼實現(xiàn)了一個用于同步隊列或條件隊列的節(jié)點數(shù)據(jù)結構,用于管理等待線程的狀態(tài)和關系。通過這些節(jié)點,可以實現(xiàn)線程的等待和喚醒機制。
以上就是AbstractQueuedSynchronizer內部類Node使用講解的詳細內容,更多關于AbstractQueuedSynchronizer內部類Node的資料請關注腳本之家其它相關文章!
相關文章
Java如何將處理完異常之后的程序能夠從拋出異常的地點向下執(zhí)行?
今天小編就為大家分享一篇關于Java如何將處理完異常之后的程序能夠從拋出異常的地點向下執(zhí)行?,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04Java集合排序規(guī)則接口Comparator用法解析
這篇文章主要介紹了Java集合排序規(guī)則接口Comparator用法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09Java?注解@PostConstruct的原理及最佳使用場景分析
@PostConstruct?是?Java?中非常實用的注解,尤其是在?Spring?等框架中,它使得開發(fā)者可以方便地在?Bean?初始化后執(zhí)行額外的操作,本文給大家介紹@PostConstruct?的原理、使用場景及最佳實踐,感興趣的朋友一起看看吧2025-04-04IntelliJ IDEA下自動生成Hibernate映射文件以及實體類
這篇文章主要介紹了IntelliJ IDEA下自動生成Hibernate映射文件以及實體類,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11Java使用POI從Excel讀取數(shù)據(jù)并存入數(shù)據(jù)庫(解決讀取到空行問題)
有時候需要在java中讀取excel文件的內容,專業(yè)的方式是使用java POI對excel進行讀取,這篇文章主要給大家介紹了關于Java使用POI從Excel讀取數(shù)據(jù)并存入數(shù)據(jù)庫,文中介紹的辦法可以解決讀取到空行問題,需要的朋友可以參考下2023-12-12