面試中如何回答Java中的鎖機制

Java中鎖機制

Java中多線程加鎖機制主要有兩種,一種是JDK實現的lock,另外一種是JVM底層實現的Synchronized關鍵字。

Synchronized是JVM底層實現的,JVM原生支持synchronized,而reentrantlock是JDK實現的,並不是所有jdk版本都支持reentrantlock,而且使用synchronized無需顯式地釋放鎖,JVM自己會保證鎖的釋放。

在JDK1.6後,對synchronized進行了很多優化,如偏向鎖、輕量級鎖等,synchronized的性能已經與Reentrantlock大致相同,除非要使用Reentrantlock的一些高級功能(實現公平鎖、中斷鎖等),一般推薦使用synchronized關鍵字來實現加鎖機制。

synchronized鎖機制原理實現

每個對象都有一個監視器鎖(monitor),一個監視器鎖只能同時最多被一個線程擁有。如果一個線程想要進入某個同步代碼塊,需要執行monitorenter字節碼指令嘗試去獲取該對象的監視器鎖的所有權,執行完同步代碼,需要執行monitorenter字節碼指令去釋放該對象的監視器鎖的所有權。這種獲取監視器鎖的操作是比較重量級的,因爲監視器鎖本質是依賴於底層操作系統的mutex lock來實現的,需要耗費較長時間。

因此,在JDK1.6,引入了偏向鎖和輕量級鎖對synchronized進行優化。一個線程嘗試去獲取一個對象的偏向鎖,會使用cas操作將這個對象的對象頭中mark work修改爲當前線程的ID,如果修改成功表示成功獲取該對象的偏向鎖,否則獲取失敗。

當兩個線程交替獲取一個對象的鎖時,偏向鎖會升級爲輕量級鎖,首先先在線程的棧幀中會建立一塊鎖記錄(lock record),將對象頭中mark word拷貝到鎖記錄中,然後將mark word更新爲指向鎖記錄的指針,並將鎖記錄中的owner指針指向鎖對象的mark word。如果更新成功,說明成功獲取該對象的輕量級鎖,否則獲取失敗,兩個線程發生競爭,進入重量級鎖的爭奪,也就是monitor鎖的競爭。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章