操作系統(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
可能餓死