renntrantlock公平鎖:
關鍵字:
t1 : 第乙個執行緒
t2 : 第二個執行緒
t3 : 第三個執行緒
head: 隊頭,也就是正在處理的執行緒
park:睡眠,發生系統呼叫,膨脹為重量級鎖
整體概念:
假如我們來拿鎖的執行緒叫是t1,t1拿鎖時由於他是第乙個執行緒,此時連佇列都無需初始化,直接拿到鎖,效能比較好。
再t1持有鎖的過程中,此時又有乙個執行緒t2前來拿鎖,此時形成佇列並進入佇列,進入佇列後判斷前乙個執行緒是否是head,如果不是,則進入park,如果是,則再一次嘗試拿鎖,發生自旋,如果拿到,執行同步**塊,如果沒拿到,則進入park。
如果這時t3來了,t3跟t2唯一的區別就是t3不會進入自旋,直接park,因為t2不是head。
總結:1.t1拿到鎖時,無需初始化佇列,效能較好。
2.如果在t1持有鎖時t2拿鎖,發生資源競爭,則生成佇列,且如果t2的秦前乙個執行緒是head,則t2會發生自旋。
3.如果所有執行緒都是交替執行,比如t1執行緒(第乙個執行緒)釋放鎖後t2執行緒(第二個執行緒)才嘗試拿鎖,那麼將永遠不會初始化佇列。
renntrantlock非公平鎖:
執行緒t1首次呼叫lock方法時候直接進行搶鎖(公平鎖的新執行緒在呼叫lock方法的時候不會上來就拿鎖),如果加鎖失敗,則判斷為何失敗,是否已被人持有,如果沒有被持有,則直接加鎖,不會判斷佇列是否有等待執行緒。如果被持有,則進入佇列,進入佇列後先判斷前面那個執行緒是否是head,如果是,則再此嘗試加鎖,成功則執行同步**,失敗則進入park。
1.執行緒呼叫lock方法時會直接進行加鎖,不會判斷佇列
2.如果加鎖失敗會再次直接加鎖,也不會判斷佇列,相當於一次自旋
3.如果加鎖再次失敗則進入佇列,且此時並未park,而是判斷前乙個執行緒是否時head,如果是,則發生自旋
4.如果自旋加鎖失敗,則呼叫park
疑問:1.什麼叫一朝排隊,永遠排隊?
2.reentrantlock的park是什麼樣的?
reentrantlock的park和sunchronized的park都一樣,都是呼叫jvm底層的c++**寫的park,都是呼叫的作業系統的park方法。但是有一點區別就是在低版本的jdk中,reentrantlock的park和sunchronized的park呼叫的不是同乙個park,也就是底層有多個park,高版本中貌似是一樣的
1.所謂的公平鎖和非公平鎖在於搶到鎖之後會不會先去判斷佇列。
2.renntrantlock預設是非公平鎖,非公平鎖的效率較高。
3.什麼場景下使用公平鎖?當後乙個執行緒的執行需要依賴前乙個執行緒執行的結果的時候,使用 公平鎖。
4.synchronized是一把非公平鎖
5.synchronized的同步**塊內部發生異常會釋放鎖,是在彙編級別進行了處理
公平鎖和非公平鎖
公平鎖和非公平鎖的不同是發生在乙個新的執行緒搶占乙個鎖的情況下。1.對於非公平鎖,當乙個新的執行緒想要得到乙個鎖,而這時鎖恰好沒有被別的執行緒占有,那麼這時候這個新的執行緒就可以無視其他執行緒在等待佇列中的排隊,而直接獲取這個鎖,而且不用先加入等待佇列。2,公平鎖,就是乙個新的執行緒想要得到乙個鎖,...
公平鎖與非公平鎖
在reentrantlock中很明顯可以看到其中同步包括兩種,分別是公平的fairsync和非公平的nonfairsync。公平鎖的作用就是嚴格按照執行緒啟動的順序來執行的,不允許其他執行緒插隊執行的 而非公平鎖是允許插隊的。預設情況下reentrantlock是通過非公平鎖來進行同步的,包括syn...
公平鎖和非公平鎖
所謂公平鎖指的是哪個執行緒先執行,那就可以先得到鎖。非公平鎖是不管執行緒是否是先執行,上來就直接嘗試占有鎖,如果嘗試失敗,就再採用類似公平鎖那種方式。我們看下reentrantlock 類的原始碼 公平鎖 protected final boolean tryacquire int acquires...