JAVA多線程(1)幾種常見鎖,及其原理

1. 用戶態和內核態

JDK早期,sync都是重量級鎖,因爲申請鎖資源必須通過kernel系統調用

ring 0,1,2,3      Linux只用了0,3

0用戶態    3內核態

 

2. CAS

不需要系統申請鎖,通過彙編指令執行

compare and swap

比較交換

JDK早期都是重量級鎖,JDK1.6優化,替換重量級鎖

java代碼跟到 compareAndGet 的native代碼

最終實現 :

cmpxchg =cas修改變量值

彙編指令:

lock cmpxchg 指令

硬件:

lock指令在執行後面指令的時候鎖定一個北橋信號

 

MarkWord

作用

記錄鎖信息

記錄gc信息

記錄hashcode

 

7.鎖升級過程

偏向鎖:沒有鎖競爭過程*(可以直接進入成重量級鎖),有個啓動過程,4s延遲後啓動偏向鎖

(偏向鎖不一定比輕量級鎖效率更高,就是因爲延遲)

偏向鎖,輕量級鎖,都是自旋鎖,不需要向系統申請鎖

自旋鎖:有競爭,等待過程自旋,需要消耗cpu資源

(輕量級鎖在線程數量不多,等待時間不長,使用)

競爭加劇,升級爲

(超過10次自旋,自旋數目超過cpu內核數的一半)

重量級鎖:進入等待隊列,不需要持續消耗cpu資源

*(等待隊列waitset)

 大小端:

網絡傳輸時:大端在前

一般都是:小端在前,大端在後

 

epoch

批量鎖偏向、批量鎖撤銷

 

 

 

Synchonized 最底層實現原理

monitorenter   鎖重入

每個對象有一個監視器鎖(monitor)。當monitor被佔用時就會處於鎖定狀態,線程執行monitorenter指令時嘗試獲取monitor的所有權,過程如下:

1、如果monitor的進入數爲0,則該線程進入monitor,然後將進入數設置爲1,該線程即爲monitor的所有者。

2、如果線程已經佔有該monitor,只是重新進入,則進入monitor的進入數加1.

3.如果其他線程已經佔用了monitor,則該線程進入阻塞狀態,直到monitor的進入數爲0,再重新嘗試獲取monitor的所有權。

monitorexit   鎖撤銷

執行monitorexit的線程必須是objectref所對應的monitor的所有者。

指令執行時,monitor的進入數減1,如果減1後進入數爲0,那線程退出monitor,不再是這個monitor的所有者。其他被這個monitor阻塞的線程可以嘗試去獲取這個 monitor 的所有權。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章