synchronized是jdk原生提供的鎖拨拓,底層由偏向鎖浙于、輕量級和重量級鎖來回切換實(shí)現(xiàn)撰豺。偏向鎖并不算鎖棕叫,它在對象頭中直接記錄偏向線程ID,認(rèn)為不會發(fā)生鎖競爭勋乾。輕量級是通過CAS來獲取鎖隶症,重量級鎖則需要通過阻塞等待來獲取鎖句狼。
當(dāng)線程執(zhí)行到synchronized代碼塊時(shí),會判斷加鎖對象頭Mark Word上鎖狀態(tài)標(biāo)識(lock status)屹堰,以此來判斷對象當(dāng)前被加鎖的級別肛冶。
鎖狀態(tài)標(biāo)識(lock status)和是否偏向共同表示5個狀態(tài)
鎖 | lock status | 是否偏向標(biāo)識(isBiased) |
---|---|---|
無鎖 | 01 | 0 |
偏向鎖 | 01 | 1 |
輕量鎖 | 00 | |
重量鎖 | 10 | |
GC標(biāo)識 | 11 |
鎖膨脹流程
鎖優(yōu)化
減少鎖占用時(shí)間街氢、減小鎖粒度扯键、鎖分離、鎖粗化珊肃、鎖擦除
減少鎖占用時(shí)間:減小加鎖代碼
減小鎖粒度:將大對象改為小對象進(jìn)行加鎖荣刑,減少鎖競爭。例如ConcurrentHashMap
鎖分離:例如讀寫鎖伦乔,讀讀不加鎖厉亏,讀寫、寫寫才加鎖
鎖粗化:將多個鎖合并成一個鎖烈和,減少鎖獲取與釋放的開銷爱只,需要考慮成本
鎖擦除:由JVM決定,例如StringBuffer雖然都帶鎖招刹,但是在局部使用不產(chǎn)生并發(fā)恬试,會將鎖擦除