线程学习(10)-monitor
synchronized加鎖操作時,是monitor在底層操作系統中完成了重量級鎖的加鎖操作,主要是通過了monitorEnter以及monitorExit完成這個操作的。那么synchronized與monitor是怎么關聯的呢?先帶個疑問。
Java對象頭簡介
以32位機器為例:
在對象頭中,普通對象的對象頭包含Mark Word,Klass Word,而數組對象多了一個array length。
Mark Word,在不同的狀態下記錄了不同的內容,后續會一一介紹。
Klass word,記錄了普通對象指針,以及元數據信息以及方法。
array length,記錄了當前數組的長度。
在以上內容中,我們主要關心mark word,這個是和monitor相關聯。
mark word結構
?mark word主要為64bit,根據對象的不同狀態,對象頭的內容也不一致,Normal(正常),Biased(偏離鎖),Lightweight Locked(輕量級鎖),Heavyweight Lock(重量級鎖)。
這里我們介紹重量級鎖,其它的后續我會另外總結的。
重量級鎖,Heavyweight Lock,64位中的結構,劃分為ptr_to_heavyweight_monitor,占據62位,以及后兩位鎖狀態10。
ptr_to_heavyweight_monitor,這個記錄的底層操作系統monitor對象所存放的地址,就是通過這個地址,依賴monitor底層對象實現了加鎖操作。
后兩位10,代表了當前鎖是重量級鎖,它是鎖狀態的一個標識。
?Monitor結構
Monitor被稱呼為監視器或者管程。
每個java對象都可以關聯一個monitor對象,如果使用Synchronized來進行加重量級鎖的話,會在Mark word中存放monitor地址,來與monitor對象相關聯。也就是我上面所說的。
那么,就看看Monitor的結構。
?Monitor主要目的是添加重量級鎖,來加鎖阻塞。就我原先線程所說的六種狀態,阻塞的狀態總共有三種,waiting,timed_waiting以及blocked。從這三種狀態來理解Monitor中的waitSet,EntryList以及Owner。
很明顯,owner代表了當前monitor對象是否被線程所持有,如果持有的話,monitor對象不為空,否則為空。
EntryList,則是存放競爭鎖失敗的線程,來對其阻塞。這里很明顯,存放的就是blocked狀態的線程。
WaitSet,就是線程已經競爭到某個鎖了,但因為某種原因,可能需要等其它線程完成,當前線程不得不調用wait方法或者join方法等等(此時該線程狀態為waiting或者timed_waiting),來等待某個線程執行完成后再次執行該線程。而這種waiting或者timed_waiting狀態的線程,就是存放至WaitSet中。
?從代碼層面簡單看一下,很簡單的代碼:
package com.bo.threadstudy.four;import lombok.extern.slf4j.Slf4j;/*** 測試操作系統底層monitor的測試類用例*/ @Slf4j public class MonitorTest {public static void main(String[] args) {Object lock = new Object();synchronized (lock){log.debug("測試");}}}運行后使用javap進行反編譯一下:
?指令這些我這不解釋了,只是在這里簡單的看一下。確實調用的是monitor。
總結
以上是生活随笔為你收集整理的线程学习(10)-monitor的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 赵鑫:简单技术指标的高明运用
- 下一篇: EasyPro_90B编程器烧录器使用操