Java-鎖升級過程

文章摘自:《Java并發編程的藝術》 提取碼: naup

Java SE 1.6為了減少獲得鎖和釋放鎖帶來的性能消耗,引入了“偏向鎖”和“輕量級鎖”,在Java SE 1.6中,鎖一共有4種狀態,級別從低到高依次是:無鎖狀態、偏向鎖狀態、輕量級鎖狀態和重量級鎖狀態,這幾個狀態會隨著競爭情況逐漸升級。鎖可以升級但不能降級,意味著偏向鎖升級成輕量級鎖后不能降級成偏向鎖。

synchronized用的鎖是存在Java對象頭里的Mark Word里面,Mark Word的存儲結構,如:

在運行期間,Mark Word里存儲的數據會隨著鎖標志位的變化而變化。Mark Word可能變化為存儲以下4種數據

升級過程

1.線程A在進入同步代碼塊前,先檢查MarkWord中的線程ID是否與當前線程ID一致,如果一致(還是線程A獲取鎖對象),則無需使用CAS來加鎖、解鎖。
2.如果不一致,再檢查是否為偏向鎖,如果不是,則自旋等待鎖釋放。
3.如果是,再檢查該線程是否存在(偏向鎖不會主動釋放鎖),如果不在,則設置線程ID為線程A的ID,此時依然是偏向鎖。
4.如果還在,則暫停該線程,同時將鎖標志位設置為00即輕量級鎖(將MarkWord復制到該線程的棧幀中并將MarkWord設置為棧幀中鎖記錄)。線程A自旋等待鎖釋放。
5.如果自旋次數到了該線程還沒有釋放鎖,或者該線程還在執行,線程A還在自旋等待,這時又有一個線程B過來競爭這個鎖對象,那么這個時候輕量級鎖就會膨脹為重量級鎖。重量級鎖把除了擁有鎖的線程都阻塞,防止CPU空轉。
6.如果該線程釋放鎖,則會喚醒所有阻塞線程,重新競爭鎖。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容