如果兩個執行緒同時將 vals 放入一棵樹中
private final void contendedLock() {
boolean waiting = false;
for (int s;;) {
if (((s = lockState) & ~WAITER) == 0) {
if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) {
if (waiting)
waiter = null;
return;
}
}
else if ((s & WAITER) == 0) {
if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) {
waiting = true;
waiter = Thread.currentThread();
}
}
else if (waiting)
LockSupport.park(this);
}
}
Thread1:CAS 鎖狀態到 WRITER
Thread2:CAS 鎖狀態為 (WRITER|WAITER)
Thread2:LockSupport.park(this)
執行緒1:解鎖根
private final void unlockRoot() {
lockState = 0;
}
那么誰能解開 Thread2 呢?
find() 方法的最后一部分需要在嚴格的條件下完成
finally {
Thread w;
if (U.getAndAddInt(this, LOCKSTATE, -READER) ==
(READER|WAITER) && (w = waiter) != null)
LockSupport.unpark(w);
}
有人能告訴我是不是我想錯了?
uj5u.com熱心網友回復:
您的推理基于這樣的假設,即 2 個撰寫器執行緒可能會進入該contendedLock()方法,而第二個撰寫器將被無限期地自行停放,這當然是不可能的,因為s 在相關樹的根節點上putVal
是同步的。
事實上,lockState僅用于通過 CAS 編排讀取器與寫入器,并且僅當讀取器和寫入器都嘗試訪問相同的 RB 樹時(即它們都對具有相同散列的鍵進行操作)。
在這種情況下,作家執行緒將公園本身,一旦發現lockState=READER(并添加WAITER位到lockState通過OR( s | WAITER),這個值(00000110)將在后面的使用finally塊由讀者取消駐留作家執行緒(一旦它通過添加清除讀取狀態-READER,即-4,并且看到之前的值也是00000110)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/400902.html
標籤:爪哇 java.util.concurrent 并发哈希图
上一篇:亂數和執行緒
下一篇:如何為雙向物體映射設計端點
