synchronized 不是自旋鎖(gold_axe)

操作系統(tǒng)os級別, 實現(xiàn)同步的方法

1.互斥量mutex:
具體是這個對象: pthread_mutex_t(互斥鎖)
拿不到鎖 就休眠



↑用法和java里面差不多
jvm里面重量鎖 就是用的這個

2.自旋鎖spinLock:
pthread_spin_t
拿不到鎖 就自旋(重試)
os空轉(zhuǎn)



使用都是差不多的

3.信號量

為什么用了 mutex 就是重量鎖? 怎么重?

因為這里會sleep()
sleep()進入內(nèi)核態(tài), 因為是系統(tǒng)調(diào)用

內(nèi)核態(tài)和用戶態(tài), 是看當(dāng)前的cpu
intel x86 CPU有四種不同的執(zhí)行級別0-3,linux只使用了其中的0級和3級分別來表示內(nèi)核態(tài)和用戶態(tài),
所謂的內(nèi)核態(tài)和用戶態(tài)其實僅僅是CPU的一個權(quán)限而已
用戶態(tài)切換到內(nèi)核態(tài)的3種方式
a. 系統(tǒng)調(diào)用
b. 異常(這個異常不是java當(dāng)中的異常)
c. 外圍設(shè)備的中斷
其實站在java程序員的角度只需要關(guān)注系統(tǒng)調(diào)用,因為系統(tǒng)調(diào)用可以認(rèn)為是用戶進程主動發(fā)起的

內(nèi)核態(tài)就是要訪問操作系統(tǒng)的那部分內(nèi)存, 因為比較危險, cpu級別上升

切換到內(nèi)核態(tài), 要先保留用戶態(tài)的線程私有信息, 這也是一種上下文切換(平時遇到的一般是同進程不同線程之間的上下文切換)

上下文切換 這4個都是 需要保留的數(shù)據(jù)不同:
進程間
內(nèi)核態(tài) 用戶態(tài)
不同進程的線程
同進程線程 ?

自旋鎖

javaer說的自旋鎖, 一般 不是指 操作系統(tǒng)的 spinLock,

而是指各種java代碼對自旋的實現(xiàn) 比如


ReentrantLock 里面有實現(xiàn)自旋, 但是沒有os自旋, 用的還是 mutex


synchronized 不是自旋鎖

synchronized 原本用的是 互斥量(就是重量鎖用的), 只有就沒有操作系統(tǒng)說的spinLock自旋鎖,

但是后來有優(yōu)化?? jvm代碼里面有自旋嗎? 沒有!

synchronized 字節(jié)碼是 monitorenter, 這個字節(jié)碼解析是

↑可以看到 么有偏向就試試輕量級鎖

輕量鎖

↑可以看到 輕量鎖 也沒有循環(huán)重試(自旋鎖實現(xiàn)), 而是 最后不行就膨脹 變成 重量鎖
ObjectMonitor* ObjectSynchronizer::inflate

↑重量鎖里面 有自旋 但是 是為了等膨脹 不是等鎖, 所以不是自旋鎖

所以結(jié)論:synchronized 從偏向 輕量 到重量 都沒自旋 不是自旋鎖

1.6以后 自適應(yīng)自旋鎖:
鎖的情況預(yù)測, 給出合適的自旋時間, 更加智能

壞處:
浪費cpu
可能餓死

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容