2017-04-01 35 views
0

我知道每個Java對象都可以用作Monitor。如果與該對象關聯的入口計數爲零,則線程可以獲取該鎖。如果同一個線程獲得鎖,則通過「monitorenter」操作碼增加入口計數,並且在「monitorexit」期間同一個線程釋放代碼時遞減入口計數。這個入口數在哪裏存儲?它如何鏈接到一個Java對象?對象創建時它是否被分配?存儲在Java中的對象的條目數在哪裏

+0

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.monitorenter是我正在閱讀的參考文獻之一。 – UnderWood

回答

0

該計數在JVM內部使用,並且不能從代碼中看到。但是,您可以自己計算它,但是請注意,即使在「synchronized」代碼中發生異常,該鎖也會被釋放(JVM中的計數器減少到0)。

2

每個JVM可能具有不同的內部鎖實現。對於HotSpot JVM,它根本不計算鎖定條目,而是在方法的堆棧幀中預留帶有monitorenter/monitorexit字節碼的時隙。

的HotSpot JVM對Java的顯示器兩種機制:

  1. 偏鎖。通過將線程ID放入對象頭中,該對象對給定線程「偏向」。然後,在給定線程中鎖定和解鎖幾乎是無操作的:JVM只需驗證Biased Lock標記仍在對象頭中。
  2. 定期遞歸鎖定。如果一種方法具有​​塊(即monitorenter/monitorexit)字節碼,則在棧上保留一個位置以記錄鎖定信息:對象及其移位的報頭(即鎖定之前的報頭值)。如果一個對象被遞歸地鎖定,被移動的頭部包含零,所以VM知道它不應該更新monitorexit上的對象頭部。

更多詳細信息請參見HotSpot sources