Java 併發程式設計(八) -- AbstractQueuedSynchronizer中的Node

我很醜發表於2020-03-13

1. 類的定義

static final class Node
複製程式碼

從類的定義可以看出

  • Node是AbstractQueuedSynchronizer中定義的一個靜態內部類
  • Node是final修飾的,不可繼承

2. 欄位屬性

//標記節點正在共享模式下等待鎖
static final Node SHARED = new Node();
//標記節點正在獨佔模式下等待鎖
static final Node EXCLUSIVE = null;

//waitStatus的值,表示執行緒已經取消
static final int CANCELLED =  1;
//waitStatus的值,表示後面的執行緒需要被喚醒
static final int SIGNAL    = -1;
//waitStatus的值,表示執行緒正在等待條件
static final int CONDITION = -2;
//waitStatus的值,表示下一個等待共享鎖的執行緒應該無條件的傳播
static final int PROPAGATE = -3;

/**
         * Status field, taking on only the values:
         *   SIGNAL:     The successor of this node is (or will soon be)
         *               blocked (via park), so the current node must
         *               unpark its successor when it releases or
         *               cancels. To avoid races, acquire methods must
         *               first indicate they need a signal,
         *               then retry the atomic acquire, and then,
         *               on failure, block.
         *   CANCELLED:  This node is cancelled due to timeout or interrupt.
         *               Nodes never leave this state. In particular,
         *               a thread with cancelled node never again blocks.
         *   CONDITION:  This node is currently on a condition queue.
         *               It will not be used as a sync queue node
         *               until transferred, at which time the status
         *               will be set to 0. (Use of this value here has
         *               nothing to do with the other uses of the
         *               field, but simplifies mechanics.)
         *   PROPAGATE:  A releaseShared should be propagated to other
         *               nodes. This is set (for head node only) in
         *               doReleaseShared to ensure propagation
         *               continues, even if other operations have
         *               since intervened.
         *   0:          None of the above
         *
         * The values are arranged numerically to simplify use.
         * Non-negative values mean that a node doesn't need to
         * signal. So, most code doesn't need to check for particular
         * values, just for sign.
         *
         * The field is initialized to 0 for normal sync nodes, and
         * CONDITION for condition nodes.  It is modified using CAS
         * (or when possible, unconditional volatile writes).
         */

//等待狀態,值為上面五種中的一種
volatile int waitStatus;
//前驅節點
volatile Node prev;
//後驅節點
volatile Node next;
//該節點排隊的執行緒
volatile Thread thread;
//連結到等待條件的下一個節點
Node nextWaiter;
複製程式碼

從欄位屬性可以看出

  • Node是一個雙向連結串列
  • Node分為共享或者獨佔兩種模式
  • Node中儲存了要執行的執行緒Thread物件
  • Node中儲存了當前等待的狀態,共有五種狀態

3. 構造方法

//空建構函式, 用來初始化AbstractQueuedSynchronizer中的head或者共享模式的Node
Node() {    // Used to establish initial head or SHARED marker
        }

//傳入一個執行緒和Node物件,在AbstractQueuedSynchronizer中的addWaiter方法中使用
Node(Thread thread, Node mode) {     // Used by addWaiter
            this.nextWaiter = mode;
            this.thread = thread;
        }

//傳入一個執行緒和等待狀態,用於Condition
Node(Thread thread, int waitStatus) { // Used by Condition
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
複製程式碼

從構造方法中可以看出

  • AbstractQueuedSynchronizer中的head 不帶Threa物件,所以head只是作為標記使用
  • Node預設是共享模式的
  • Node中的Thread是核心

4. 方法

isShared 方法

//獲取當前節點的模式
final boolean isShared() {
            return nextWaiter == SHARED;
        }
複製程式碼

predecessor 方法

//獲取前驅節點,如果前驅節點不存在丟擲異常
final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }
複製程式碼

相關文章