reentrantlock的實現原理分析
重入鎖提供了兩種實現,
怎麼理解公平和非公平呢?
反之,就是不公平的。
簡單來說公平鎖就是等待時間最長的執行緒最優先獲取鎖。
非公平鎖的實現流程時序圖
原始碼分析
並且sync有兩個實現,
我們先來分析一下非公平鎖的實現::
final
void lock()
所以在這裡,是表示當前的state
由於reentrantlock是可重入鎖,
每次加鎖都會將state的值+1,
解鎖時每解一次鎖就會將state減1,
abstractqueuedsynchronizer.acquire
當多個執行緒同時進入這個方法時,
public
final
void
acquire(int arg)
ø 否則,自旋獲取鎖,並且判斷中斷標識,
ø addwaiter方法把當前執行緒封裝成node,
nonfairsync.tryacquire
protected
final
boolean
tryacquire(int acquires)
nofairtryacquire
這裡的實現邏輯類似synchroized關鍵字的偏向鎖的做法,
final
boolean nonfairtryacquire(int acquires)
}else
if (current == getexclusiveownerthread())
//如果狀態不為0,且當前執行緒不是owner,則返回false。
return
false; //獲取鎖失敗,返回false
}
addwaiter
private node addwaiter(node mode)
}enq(node); // 如果隊列為null或者cas設定新的tail失敗
return node;
}
enq
private node enq(final node node) else }}
}
**執行到這裡,aqs佇列的結構就是這樣乙個表現::
這個方法主要用於爭搶鎖
final
boolean acquirequeued(final node node, int arg)
//如果獲取鎖失敗,則根據節點的waitstatus決定是否需要掛起執行緒
if (shouldparkafte***iledacquire(p, node) &&
parkandcheckinterrupt())// 若前面為true,則執行掛起,待下次喚醒的時候檢測中斷的標誌
interrupted = true;
}} finally
}
原來的head節點釋放鎖以後,會從佇列中移除,
對於第三個及以後的節點,if (p == head)條件不成立,
方法是判斷乙個爭用鎖的執行緒是否應該被阻塞。
所以它可以安全的阻塞了,返回true
private
static
boolean
shouldparkafte***iledacquire(node pred, node node) while (pred.waitstatus > 0);
pred.next = node;
} else
return
false;
}
解讀:假如有t1,t2兩個執行緒都加入到了鍊錶中
而head以及thread1的的awaitstatus都是signal,
signal:值為-1,
condition:值為-2,
propagate:值為-3,
parkandcheckinterrupt
它是通過locksupport.park(this)將當前執行緒掛起到wating狀態,
private
final
boolean
parkandcheckinterrupt()
reentrantlock.unlock
public
final
boolean
release(int arg)
return
false;
}
tryrelease
在排它鎖中,加鎖的時候狀態會增加1(當然可以自己修改這個值),
在解鎖的時候減掉1,同乙個鎖,在可以重入後,可能會被疊加為2、3、4這些值,
protected
final
boolean
tryrelease(int releases)
setstate(c);
return free;
}
unparksuccessor
private
void
unparksuccessor(node node)
if (s != null)
locksupport.unpark(s.thread);
}
locksupport.unpark(s.thread);
unpark函式為執行緒提供「許可(permit)」,
permit相當於0/1的開關,預設是0,
這時呼叫unpark會把permit設定為1.
在使用locksupport之前,
總結移出佇列(或停止自旋)的條件是
在釋放同步狀態時,同步器呼叫tryrelease(int arg)方法釋放同步狀態,
AbstractCollection原始碼分析
abstractcollection抽象類提供了collection的骨架實現,collection分析請看 這裡直接看它的 是如何實現的.public abstract iterator iterator 該方法沒有實現.public abstract int size 該方法沒有實現.publi...
ThreadPoolExecutor原始碼閱讀
執行緒池解決兩個問題 一是復用執行緒,減少建立銷毀執行緒帶來系統開銷 二是限定系統資源使用邊界,避免大量執行緒消耗盡系統記憶體 適用於互不依賴,執行時間短,不需要對執行緒控制操作的執行緒 新增任務時,1.若執行緒數量小於corepoolsize,則新增執行緒執行任務 2.若執行緒數量大於等於core...
OrangePi One Android 原始碼編譯
一 系統環境搭建參照 二 lichee原始碼編譯 1.檢視help build.sh h2.配置核心 cd linux 3.4 make arch arm menuconfig 進入配置頁面,上下移動列表,空格是選擇列表,左右移動選擇退出選項 3.首次編譯執行清除 在 lichee linux3.4...