synchronized的實現原理
synchronized在JVM中是基于monitor對象實現方法同步和代碼塊同步辩棒,雖然細節(jié)不同但都是通過成對對monitorEnter和monitorExit來控制實現宋税。
對同步塊,MonitorEnter指令插入在同步代碼塊的開始位置炊琉,當代碼執(zhí)行到該指令時,將會嘗試獲取該對象Monitor的所有權惶室,即嘗試獲得該對象的鎖温自,而monitorExit指令則插入在方法結束處和異常處玄货,JVM保證每個MonitorEnter必須有對應的MonitorExit皇钞。
對同步方法,從同步方法反編譯的結果來看松捉,方法的同步并沒有通過指令monitorenter和monitorexit來實現夹界,相對于普通方法,其常量池中多了ACC_SYNCHRONIZED標示符隘世。
JVM就是根據該標示符來實現方法的同步的:當方法被調用時可柿,調用指令將會檢查方法的 ACC_SYNCHRONIZED 訪問標志是否被設置,如果設置了丙者,執(zhí)行線程將先獲取monitor复斥,獲取成功之后才能執(zhí)行方法體,方法執(zhí)行完后再釋放monitor械媒。在方法執(zhí)行期間目锭,其他任何線程都無法再獲得同一個monitor對象。
javap -c SynAddTest反編譯后
synchronized使用的鎖是存放在Java對象頭里面
具體位置是對象頭里面的MarkWord纷捞,MarkWord里默認數據是存儲對象的HashCode等信息
鎖信息
但是會隨著對象的運行改變而發(fā)生變化痢虹,不同的鎖狀態(tài)對應著不同的記錄存儲方式
詳細對鎖信息
鎖對狀態(tài)及升級
無鎖->偏向鎖->輕量級鎖->重量級鎖:
并且四種狀態(tài)會隨著競爭的情況逐漸升級,而且是不可逆的過程