09 Java多執行緒 2 AQS CLH佇列

2021-09-24 03:18:33 字數 1928 閱讀 9775

三、node操作方法

3.2 sethead出列

四、小結

clh locks ( craig, landin, and hagersten, clh鎖 ) 是自旋鎖,能夠確保無飢餓,能夠保證先來先服務的公平性。

static

final

class

node

/** * returns previous node, or throws nullpointerexception if null.

* use when predecessor cannot be null. the null check could

* be elided, but is present to help the vm.

** @return the predecessor of this node

* 返回當前節點的前驅節點,null檢查可以被省略,但是有助於vm

*/final node predecessor()

throws nullpointerexception

node()

node

(thread thread, node mode)

node

(thread thread,

int waitstatus)

}

字段

含義waitstatus

等待狀態,用來控制線程的阻塞和喚醒,並且可以避免不必要的#park(…)和#unpark(…) 方法。他的值為:signal/cancelled/condition/propagate/0 ,0位初始狀態。

prev 和 next

分別指向當前node的前驅和後繼節點

head 和 tail

分別指向當前node鍊錶的頭結點和尾節點

thread

node節點對應的執行緒

nextwaiter

condition佇列的下乙個等待的執行緒(共享模式則是乙個特殊值shared = new node())

3.1.1 **

/**

* 將當前執行緒按照指定的模式,建立乙個node物件,並加入佇列

*/private node addwaiter

(node mode)

}//6.如果快速嘗試失敗,那就進入enq方法進行多次嘗試,直到成功

enq(node)

;return node;

}/**

* 自旋設定node為尾節點,直到成功

*/private node enq

(final node node)

else

//6.如果設定失敗(比如**a和b之間其他執行緒設定了尾節點,那麼cas會失敗),就會進

// 入下一次迴圈,下一次就會重新獲取node t = tail;並設定node.prev = t;,就會

// 成功了,即使不成功,又會繼續迴圈,其實只要ab之間沒有被其他執行緒設定就會成功,

//cas這樣其實不會進入死迴圈,因為每次嘗試都會獲取到新的tail,然後cas設定新的

// tail為node,但是可能會有執行緒自旋太久}}

}

3.1.2 入列示意圖

* 將node設定為佇列的頭結點

*/private

void

sethead

(node node)

3.2.2 出列示意圖

java多執行緒(2)

1.synchronized 鎖重入 執行緒請求由自己持有的物件時,如果該鎖是重入鎖,請求就會成功,否則阻塞 2.synchronized出現異常時,鎖自動釋放 3.當多個執行緒要同乙個例項時 雙重校驗鎖 public class dubblesingleton catch interruptede...

Java多執行緒2 執行緒的建立

上一講中我們講了什麼是執行緒,這一講我們細細討論一下關於執行緒的那些事。先看看執行緒的狀態轉換圖。1.首先執行緒被建立出來。2.進入就緒佇列中等待cpu分配時間片 這裡的時間片指的是cpu允許執行緒執行的最大時間 若在規定時間內未執行完成,則執行緒繼續進入就緒佇列等待cpu分配時間片。3.執行緒進入...

Java多執行緒2 synchronized

先看一段 public class account public void deposit int my catch interruptedexception e this.money tmp public void withdraw int my catch interruptedexceptio...