Monitor概念
Monitor概念
Monitor 被翻譯為監視器或管程
每個 Java 對象都可以關聯一個 Monitor 對象, 如果使用 synchronized 給對象上鎖(重量級)之后,該對象頭的 Mark Word 中就被設置指向 Monitor 對象的指針
Monitor 結構如下
- 剛開始 Monitor 中 Owner 為 null
- 當 Thread-0 執行 synchronized(object) 上鎖就會將 Monitor 的所有者 Owner 置為 Thread-0, 同時對象 object 中的 Mark Word 的 state 也會發生相應改變。
- 在 Thread-0 上鎖的過程中,如果 Thread-1, Thread-2, Thread-3 也來執行 synchronized(object), 就會進入 EntryList 變成 BLOCKED 狀態
- Thread-0 執行完同步代碼塊的內容,然后喚醒 EntryList 中等待的線程來競爭鎖,競爭時是非公平的
- 圖中 WaitSet 中的 Thread-4, Thread-5 是之前獲得過鎖,但條件不滿足進入 WAITING 狀態的線程,可以由 notifyAll() , notify() 喚醒
注意:
- synchronized 必須是進入同一個對象的 monitor 才有上述的效果
- 不加 synchronized 的對象不會關聯監視器,不遵從以上規則
**Java 對象頭 **
以 32 位虛擬機為例
普通對象
|----------------------------------------------------------| | Object Header (64 bits) | |----------------------------------------------------------| | Mark Word (32 bits) | Klass Word (32 bits) | |----------------------------------------------------------|Mark Word : 用于存儲對象自身的運行時數據, 如哈希碼 (HashCode) 、GC 分代年齡、鎖狀態標志、線程持有的鎖、偏向線程ID等。同時考慮到虛擬機的空間效率,Mark Word 被設計成一個有著動態定義的數據結構。
Klass Word: 類型定義信息 , Java 虛擬機通過這個指針來確定該對象是哪個類的實例(并不是所有的虛擬機都必須在對象數據上保留類型指針)。此外,如果對象是一個 Java 數組,那在對象頭中還必須有一塊用于記錄數組長度的數據,因為如果數組的長度是不確定的,將無法推斷出數組的大小。
數組對象
|--------------------------------------------------------------------------------------| | Object Header (96 bits) | |--------------------------------------------------------------------------------------| | Mark Word (32 bits) | Klass Word (32 bits) | array length (32bits) | |--------------------------------------------------------------------------------------|其中 Mark Word 結構 (動態數據結構)為
| 對象哈希碼、對象分代年齡 | 01 | 未鎖定 |
| 指向鎖記錄的指針 | 00 | 輕量級鎖定 |
| 指向重量級鎖的指針 | 10 | 膨脹(重量級鎖定) |
| 空,不需要記錄信息 | 11 | GC標記 |
| 偏向線程ID、便向時間戳、對象分代年齡 | 01 | 可偏向 |
32 位虛擬機
|-------------------------------------------------- |-----------------------------------| | Mark Word (32 bit) | State | |-------------------------------------------------- |-----------------------------------| | hashcode:25 | age:4 | biased_block:0 |01 | Normal | |-------------------------------------------------- |-----------------------------------| | thread:23 |epoch:2| age:4 | biased_block:1 |01 | Biased | |-------------------------------------------------- |-----------------------------------| | ptr_to_lock_record:30 |00 | LightWeight Locked | |-------------------------------------------------- |-----------------------------------| | ptr_to_heavyweight_monitor:30 |10 | HeavyWeight Locked | |-------------------------------------------------- |-----------------------------------| | |11 | Marked for GC | |-------------------------------------------------- |-----------------------------------|64 位虛擬機
|-------------------------------------------------------------|-------------------------| | Mark Word (64 bit) | State | |-------------------------------------------------------------|-------------------------| | unused:25 | hashcode:31 | unused:1 | age:4 | biased_block:0 | 01 | Normal | |-------------------------------------------------------------|-------------------------| | thread:23 | epoch:2 | unused:1 | age:4 | biased_block:1 | 01 | Biased | |-------------------------------------------------------------|-------------------------| | ptr_to_lock_record:62 | 00 | LightWeight Locked | |-------------------------------------------------------------|-------------------------| | ptr_to_heavyweight_monitor:62 | 10 | HeavyWeight Locked | |-------------------------------------------------------------|-------------------------| | | 11 | Marked for GC | |-------------------------------------------------------------|-------------------------|[深入理解 Java 虛擬機 第三版]:
總結
- 上一篇: jvm:ObjectMonitor源码
- 下一篇: 即使被拖库,也可以保证密码不泄露(一种安