JAVA synchronized鎖升級,可重入,非公平
- 提示
- 鎖升級
- 偽代碼
- 鎖升級程序
提示
年輕人不講理論
鎖升級
無鎖 → 偏向鎖 → 輕量級鎖 → 重量級鎖
偽代碼
//偽代碼
class A{
synchronize hello(){
hi();
}
synchronize hi(){
sout("hi")
}
main(){
A a = new A();
new Thread( a.hello(), "1執行緒").start;
new Thread( a.hello(), "2執行緒").start;
new Thread( a.hello(), "3執行緒").start;
new Thread( a.hello(), "4執行緒").start;
}
}
鎖升級程序
最復雜情況下:
-
1執行緒呼叫a物件hello方法,需要鎖住a物件,查看a物件頭存盤的鎖標志為無鎖,鎖狀態state=0,將鎖標志改為偏向鎖,a物件頭中設定正在運行的執行緒id為1執行緒的id,將鎖狀態state++
-
1執行緒呼叫hi方法,需要鎖住a物件,查看物件頭鎖標志為偏向鎖,擁有鎖的執行緒id和自己執行緒id一致,不需要搶奪鎖,只需要將鎖狀態state++(可重入)
-
1執行緒呼叫未結束
-
2執行緒呼叫a物件hello方法,需要鎖住a物件,查看a物件頭存盤的鎖標志為偏向鎖,將鎖標志改為輕量級鎖,2執行緒做CAS自旋,回圈獲取鎖
-
3執行緒呼叫a物件hello方法,需要鎖住a物件,查看a物件頭存盤的鎖標志為輕量級鎖,3執行緒直接做CAS自旋,回圈獲取鎖
-
2,3執行緒回圈時間達到閾值,或者多個執行緒都在此自旋(自旋浪費cpu),將a物件頭中的鎖標志改為重量級鎖
-
2,3執行緒查看a物件頭鎖標志為重量級鎖,直接將執行緒放入a物件頭中的執行緒等待佇列,不再自旋
-
4執行緒呼叫a物件hello方法,需要鎖住a物件,查看a物件頭存盤的鎖標志為重量級鎖,直接進入等待佇列
-
1執行緒呼叫hi結束,state - -
-
1執行緒呼叫hello結束, state - -
-
1執行緒釋放鎖并喚醒其它等待執行緒(非公平鎖)
-
等待執行緒并不是按排隊順序獲取鎖,而是一起搶奪鎖(非公平鎖)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/272364.html
標籤:其他
