synchronized 鎖升級機制也叫做鎖膨脹機制,此機制誕生於 JDK 6 中。在 Java 6 及之前的版本中,synchronized 的實現主要依賴於作業系統的 mutex 鎖(重量級鎖),而在 Java 6 及之後的版本中,Java 對 synchronized 進行了升級,引入了鎖升級的機制,可以更加高效地利用 CPU 的多級快取,提升了多執行緒併發效能。
synchronized 鎖升級的過程可以分為以下四個階段:無鎖狀態、偏向鎖、輕量級鎖和重量級鎖。其中,無鎖狀態和偏向鎖狀態都屬於樂觀鎖,不需要進行鎖升級,鎖競爭較少,能夠提高程式的效能。只有在鎖競爭激烈的情況下,纔會進行鎖升級,將鎖升級為輕量級鎖狀態。
下面是 synchronized 鎖升級的具體流程:
1.無鎖狀態 當前無任何執行緒獲取它,所以此過程不需要加鎖,是無鎖狀態。當一個執行緒訪問一個同步塊時,如果該同步塊沒有被其他執行緒佔用,那麼該執行緒就可以直接進入同步塊,並且將同步塊標記為偏向鎖狀態。
2.偏向鎖狀態 在偏向鎖狀態下,同步塊已經被一個執行緒佔用,其他執行緒訪問該同步塊時,只需要判斷該同步塊是否被當前執行緒佔用,如果是,則直接進入同步塊。這個過程不需要進行任何加鎖操作,仍然屬於樂觀鎖狀態。
3.輕量級鎖狀態 如果在偏向鎖狀態下,有多個執行緒競爭同一個同步塊,那麼該同步塊就會升級為輕量級鎖狀態。此時,每個執行緒都會在自己的 CPU 快取中儲存該同步塊的副本,並透過 CAS(Compare and Swap)操作來對同步塊進行加鎖和解鎖。這個過程需要進行加鎖操作,但相對於傳統的 mutex 鎖,輕量級鎖的效率要高很多。
4.重量級鎖狀態 輕量級鎖之後會透過自旋來獲取鎖,自旋執行一定次數之後還未成功獲取到鎖,此時就會升級為重量級鎖,並且進入阻塞狀態。
synchronized 鎖升級的過程可以有效地減少鎖競爭,提高多執行緒併發性。