1. 程式人生 > >synchronize的實現原理(偏向鎖)

synchronize的實現原理(偏向鎖)

1 介紹

 當一個執行緒試圖訪問同步的程式碼時,會首先嚐試獲取鎖。執行完畢或者丟擲異常的時候會主動釋放鎖。否則會一直阻塞著。

    1.1 實現原理

    從JVM規範中可以看到synchronize的實現主要是基於monitor物件來實現的。monitorenter是在編譯後插入同步程式碼開始的位置,而monitorexit是在程式碼的結束處和異常處。

任何一個物件都有一個monitor與之關聯。

2 建立鎖

 java中每一個物件都可以作為鎖,對於普通的方法。鎖是當前物件的例項,對於靜態方法,鎖是當前的class物件。同步塊,則是括號裡面配置的物件。

3 鎖的升級

java6之後為了解決synchronize鎖效能的銷號(獲取和釋放)。引入了偏向鎖,和輕量級鎖的概覽

當前版本中鎖的狀態從低到高總共有四種:無鎖狀態->偏向鎖狀態->輕量級鎖狀態->重量級鎖狀態。需要注意的是,鎖可以升級缺不可以降級

    3.1 偏向鎖

     3.1.1 獲取

     簡單的理解,偏向於這個執行緒。 當一個執行緒進入同步塊,首先測試 物件的mark word 中的threadId是否等同當前執行緒ID,如果成功,則獲取鎖成功,否則。首先測試mark word中的鎖標識是否為1 。如果沒有設定。則升級鎖。否則 通過CAS操作,將自己的執行緒ID 嘗試放入 的mark word 的位置。如果成功則獲取鎖成功。否則,說明物件存在競爭。將會在適當的地方掛起獲取鎖的執行緒。然後升級鎖。接著執行程式碼。

    偏向鎖預設為開啟狀態。只是會在應用啟動後延遲啟動通過引數可以設定不延時XX:BiasedLockingStartupDelay=0。如果你確定應用程式裡所有的鎖通常情況下處於競爭狀態,可以通過JVM引數關閉偏向鎖:-XX:-UseBiasedLocking=false,那麼程式預設會進入輕量級鎖狀態。

    3.1.2 釋放

    偏向鎖使用了只有出現競爭的情況下才會釋放。首先他會在一個安全點暫停持有鎖的物件。然後升級鎖。