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 的所有權。