故事人物。
老王 - JVM
Xiao Nan - 執行緒.
小女孩 - 執行緒。
房間 - 物件。
在房間的門上 - 防盜鎖 - 顯示器重量級鎖。
房間上門-小楠書包-輕量鎖。
在房間的門上 - 刻有小南的名字 - 偏置鎖 - 該物體是執行緒獨有的。
批量重新寫入 - 一類偏置鎖撤銷達到 20 閾值 - 批量重新偏置。
無法雕刻名稱 - 批量撤銷對此類物件的偏差鎖定,並將該類設定為無偏差。
小楠想利用這個房間來保證計算不受其他人的干擾(原子性),最初,他在切換上下文時用防盜鎖鎖住了門。 這樣一來,就算他走了,別人也進不了門,他的工作也安全了。
然而,在許多情況下,沒有人與他爭奪使用房間的權利。 小姑娘想用房間,但是用的時間錯開,小楠白天用,小姑娘晚上用。 每次都鎖起來太麻煩了,有沒有更簡單的方法?
蕭楠和小姑娘商量了一下,答應不鎖門,但誰用了房間,誰把書包掛在門口,可是他們的書包都是一樣的款式,所以每次進門前,他們都要翻閱書包,看看課本是誰,是不是自己的, 然後他們就可以進門了,這樣一來,這個省就被鎖住了,也沒上鎖了。如果包不是你自己的,那就在門外等著,下次通知對方鎖門。
後來,小女孩回到了老家,很長一段時間都不會使用這個房間。 小楠還是每次都掛著書包,翻著書包,雖然比鎖門容易,但是他還是覺得麻煩。
於是,蕭楠乾脆在門上刻上了自己的名字:【蕭楠的專屬房間,別人不該用],下次你來用房間的時候,只要名字還在,那就說明沒有人打擾你,你還是可以放心使用的房間。 如果在此期間有人想使用這個房間,那麼使用者將刪除小楠的名字,並將其公升級為書包。
同學們都回老家過節了,小楠膨脹了,在20個房間裡刻下了自己的名字,他想進去就進去什麼。 後來,他回老家度假,這時小姑娘回來了(她也不得不使用這些房間),結果他不得不把蕭南可的名字一一抹掉,公升級為掛書包的方式。 老王覺得成本有點高,提出了批量重刻的方法,他讓小女孩不用掛書包,可以直接在門上刻上自己的名字。
後來,刻名字的現象越來越頻繁,老王也受不了了:算了,這些房間是不能刻的,只能掛書包---設定了這種不偏不倚。
它反映在節程式碼指令中。輕量級鎖的用例:如果乙個物件有多個執行緒需要鎖定,但鎖定時間是錯開的(即沒有爭用),則可以使用輕量級鎖進行優化。
如果有競爭,輕量級鎖公升級為重量級鎖。
輕量級鎖對消費者是透明的,即語法保持不變synchronized
假設有兩種方法可以同步塊,鎖定同乙個物件。
static final object obj = new object();public static void method1() public static void method2()建立乙個鎖記錄物件,每個執行緒的棧幀都會包含乙個鎖記錄結構,可以儲存鎖物件的標記字
讓鎖記錄中的物件引用指向鎖物件,並嘗試將物件的標記字替換為 cas(比較和交換、原子性),並將標記字的值儲存在鎖記錄中。
如果 CAS(比較和交換)替換成功,則物件將儲存在標頭中鎖記錄位址和狀態 00
,表示執行緒已鎖定物件,如下所示。
如果 CAS(比較和交換)失敗,有兩種情況。
如果另乙個執行緒已在物件上持有輕量級鎖,則表示存在爭用,並且鎖擴充套件過程開始。
如果你自己做同步鎖重入器,然後新增鎖定記錄作為重入計數,如示例中所示。
退出同步塊時(解鎖時),如果存在值為 null 的鎖定記錄,則表示存在 reentriency,然後重置鎖定記錄,這意味著 reentrancy count 為負 1(鎖定重入者數)。
退出同步塊時(解鎖時),鎖定記錄的值不為空,則使用 CAS(比較和交換、原子性)將標記字的值恢復到物件標頭。
如果成功,則解鎖將成功。
如果失敗,則輕量級鎖已充氣或公升級為重量級鎖,並且重量級鎖的解鎖過程已經開始。
如果 CAS 操作在嘗試新增輕量級鎖時失敗,則另乙個執行緒會向物件新增輕量級鎖(存在爭用),並且需要鎖擴充套件才能將輕量級鎖轉換為重量級鎖。
static object obj = new object();public static void method1()當 thread-1 執行輕量級鎖時,thread-0 已對物件具有輕量級鎖。
此時,thread-1 和輕量級鎖失敗,進入鎖擴容過程。
即為物件物件申請乙個監視器鎖,讓物件指向重量級鎖位址。
然後進入監視器的進入列表,自己被阻止
當 thread-0 退出同步塊解鎖時,使用 cas 將標記字的值恢復到物件標頭失敗。 這時會進入重量級的解鎖過程,即根據監控位址找到監控物件,將 owner 設定為 null,喚醒 entrylist 中阻塞的執行緒。
Spin 還可用於優化重量級鎖何時處於爭用狀態,以便如果當前執行緒成功旋轉(即,保持鎖的執行緒已退出同步塊並釋放鎖),則當前執行緒可以避免阻塞。
旋轉重試成功的條件。
執行緒 2 旋轉重試 3 次以成功鎖定,以免被阻塞。
旋轉重試失敗的情況。
執行緒 2 一直在旋轉,最終被阻塞。
旋轉占用 CPU 時間,單核 CPU 旋轉是浪費,多核 CPU 旋轉是優勢。
在 J**A 6 之後,自旋鎖是自適應的,例如,如果物件剛剛在一次自旋操作中成功,那麼它認為自旋成功的概率會很高,所以它多旋轉幾次;相反,旋轉更少甚至沒有旋轉,總之,它更聰明。
j**a 7 之後,您將無法控制是否開啟旋轉功能。
輕量級鎖仍然需要執行 CAS 操作,每次在沒有爭用的情況下(在其自己的執行緒中)重新進入鎖。
在 J**A 6 中,引入了偏置鎖定進行進一步優化:只有第一次使用 CAS 將執行緒 ID 設定為物件的標記字頭,然後發現執行緒 ID 是你自己的,就意味著沒有爭用,也不需要重新 CAS。 將來,只要沒有競爭,物件就歸執行緒所有。
例如:
static final object obj = new object();public static void m1() public static void m2() public static void m3()
呼叫物件標頭格式。
|--mark word (64 bits) |state | unused:25 | hashcode:31 | unused:1 | age:4 | biased_lock:0 | 01 | normal |正常 |- 偏置鎖 | thread:54 | epoch:2 | unused:1 | age:4 | biased_lock:1 | 01 | biased | ptr_to_lock_record:62 | 00 | lightweight locked |輕量級 |- 重量級 | ptr_to_he**yweight_monitor:62 | 10 | he**yweight locked | 11 | marked for gc |建立物件時:
如果啟用了偏置鎖定(預設啟用),則在建立物件後,標記字值為 0x05,即最後 3 位為 101,其執行緒、紀元和年齡均為 0
偏置鎖預設是延時的,程式啟動時不會立即生效,休眠4s後可以勾選,如果想避免延時,可以新增vm引數-xx:biasedlockingstartupdelay=0
以禁用延遲。
如果未啟用偏置鎖,則在建立物件後,標記字值為0x01,即最後 3 位為 001,則其雜湊碼和年齡為 0,首次使用雜湊碼時會賦值。
class dog {}利用 JOL 第三方工具檢視物件標頭資訊。
POM 檔案。
org.openjdk.jol jol-core 0.10注意這個小節的**來理解它,機器沒有執行成功,只是注意輸出
新增 VM 引數 -xx:biasedlockingstartupdelay=0 public static void main(string args) throws ioexception logdebug("同步"); system.out.println(classlayout.toprintable***true));"t1").start();輸出。
11:08:58.117 c.testbiased[t1] -同步 11:0 00000101 8:58121 c.testbiased [t1] -synchronized 00000000 00000000 00000000 000000000 00000000 00011111 11101011 110100000 00000101與上面輸出的差異,檢視 11:08:58121 c.testbiased [t1] - 在 00000000 00000000 0000000 0000000 00011111 11101011 11010000 00000101處於偏置鎖中後同步,除非有新的爭用,否則執行緒 ID 保持不變
注意當處於偏置鎖中的物件被解鎖時,執行緒 ID 仍儲存在物件標頭中。在測試執行時上方新增 VM 引數
-xx:-usebiasedlocking
禁用偏置鎖定。
輸出。
11:13:10.018 c.testbiased [t1] -同步了第乙個 00000000 000000000 000000000 0000000000 0000000000 00000000000 0000000000 00000001 三個日誌的最後三位數字不是 101 11:13:10021 c.testbiased[t1] -在 00000000 000000000 00000000 00000000 0000000 001000000 00010100 11110011 10001000 中同步 輕量級鎖 11:13:10021 c.testbiased [t1] -synchronized 0000000000 0000000000 000000000000 00 00 00000001 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004) 測試雜湊碼並新增 VM 引數
-xx:biasedlockingstartupdelay=0
以禁用延遲。
正常狀態物件開始時沒有雜湊碼,並在第一次呼叫時生成。
呼叫雜湊碼會導致偏置鎖被禁用。 因為如果處於偏鎖狀態,執行緒id已經儲存好了,然後又儲存了雜湊碼,空間不夠,所以無法儲存。 所以此時狀態會變為正常狀態。 此外,輕量級鎖的雜湊碼儲存在堆疊幀的鎖記錄中,重量級鎖的雜湊碼儲存在監控物件中,解鎖時會恢復。
呼叫物件的雜湊碼,但執行緒 ID 儲存在偏鎖物件的標記字中,如果呼叫了雜湊碼,則偏置鎖將被撤銷。
輕量級鎖在鎖記錄中記錄雜湊碼
重量級鎖在監視器中記錄雜湊碼
呼叫雜湊碼後使用偏置鎖,記得刪除它們-xx:-usebiasedlocking
輸出。
11:22:10.386 c.testbiased [main] - 呼叫雜湊程式碼:1778535015 11:22:10391 c.testbiased [t1] -同步前端 00000000 00000000 00000000 01101010 00000010 01001010 01100111 00000001 11:22:10393 c.testbiased[t1] -同步 00000000 000000000 000000000 000000000 001000000 11000011 11110011 01101000 11:22:10393 c.testbiased [t1] -在 00000000 00000000 00000000 01101010 00000010 01001010 01100111 00000001後同步當其他執行緒使用偏置鎖物件時,偏置鎖將公升級為輕量級鎖。
private static void test2() 丟擲 interruptedException 鎖當前類物件同步 (testbiased.)。類)如果不使用 wait notify 來使用 join,則必須開啟以下注釋,因為:t1 執行緒無法結束,否則底層執行緒可能會被 jvm 作為 t2 執行緒復用,並且底層執行緒 id 相同 *try catch (ioexception e) * },"t1"); t1.start();thread t2 = new thread(()catch (interruptedexception e) log.debug(classlayout.parseinstance(d).toprintable***true));synchronized (d) log.debug(classlayout.parseinstance(d).toprintable***true));"t2"); t2.start();輸出。
[t1] -000000000 00000000 00000000 00000000 00011111 01000001 00010000 00000101處於偏置鎖定狀態 [t2] -0000000000 000000000 00000000 00011111 01000001 00010000 00000101 T2 執行緒未鎖定且 T1 一致 [T2] -00000 00000 00000000 000000000 00000000 00011111 10110101 11110000 010000000 在輕量級鎖 [t2] -0000000000 00000000 0000000000 000000000000 0000000000 解鎖後00000001是無偏的在這種情況下,偏置鎖也會被撤銷。 因為等待通知僅適用於重量級鎖。 偏置鎖或輕量級鎖公升級為重量級鎖。
public static void main(string args) throws interruptedexception catch (interruptedexception e) log.debug(classlayout.parseinstance(d).toprintable***true));"t1"); t1.start();new thread(()catch (interruptedexception e) synchronized (d) "t2").start();輸出。
[t1] -0000000000 000000000 000000000 000000000 000000000 000000000 000000000 00000101 偏置鎖定 [t1] -000000000 000000000 00000000 00011111 10110011 11111000 00000101鎖 [t2] -notify [t1] - 00000000 00000000 00000000 00000000 00011100 11010100 00001101 11001010重量級鎖如果乙個物件被多個執行緒訪問,但沒有競爭,則偏向執行緒 t1 的物件仍有機會重新偏向到 t2,這將重置物件的執行緒 ID
當吊銷偏置鎖定閾值超過 20 次時,JVM 會認為我是否偏錯了,並在鎖定這些物件時重新偏向鎖定的執行緒。
private static void test3() throws interruptedexception }synchronized (list) "t1"); t1.start();thread t2 = new thread(()catch (interruptedexception e) log.debug("***"); for (int i = 0; i < 30; i++)log.debug(i + "\t" + classlayout.parseinstance(d).toprintable***true));"t2"); t2.start();輸出。
[t1] -0 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 //- 偏置鎖 |t1] -1 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -2 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -3 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -4 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -5 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -6 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -7 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -8 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -9 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -10 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -11 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -12 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -13 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -14 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -15 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -16 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -17 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -18 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -19 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -20 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -21 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -22 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -23 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -24 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -25 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -26 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -27 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -28 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t1] -29 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -t2] -0 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 //偏置到 T1 鎖定 [t2] -0 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 //撤銷偏置鎖,公升級到輕量級鎖 [.]t2] -0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 //在非偏置鎖定中,也就是說,正常狀態 [t2] -1 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -1 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -1 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -2 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -2 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -2 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -3 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -3 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -3 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -4 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -4 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -4 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -5 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -5 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -5 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -6 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -6 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -6 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -7 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -7 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -7 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -8 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -8 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -9 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -9 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -9 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -10 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -10 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -10 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -11 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -11 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -11 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -12 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -12 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -12 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -13 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -13 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -13 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -14 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -14 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -14 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -15 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -15 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -15 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -16 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -16 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -16 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -17 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -17 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -17 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -18 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -18 00000000 00000000 00000000 00000000 00100000 01011000 11110111 00000000 [t2] -18 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001 [t2] -19 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 //第 20 個物件開始,所有這些都處於偏向 t2 的偏置鎖中 [t2] -19 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 //批量復偏置,後者都是偏向 t2 的偏置鎖t2] -19 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -20 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -20 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -20 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -21 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -21 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -21 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -22 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -22 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -22 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -23 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -23 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -23 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -24 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -24 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -24 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -25 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -25 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -25 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -26 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -26 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -26 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -27 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -27 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -27 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -28 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -28 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -28 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -29 00000000 00000000 00000000 00000000 00011111 11110011 11100000 00000101 [t2] -29 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101 [t2] -29 00000000 00000000 00000000 00000000 00011111 11110011 11110001 00000101當吊銷偏置鎖定閾值超過 40 倍時,JVM 認為它確實存在偏置,根本不應該偏置。 因此,整個類中的所有物件都變得無偏,並且新建立的物件也是無偏的。
這裡就不列印日誌了,你可以自己想想。
static thread t1,t2,t3; private static void test4() throws interruptedexception }locksupport.unpark(t2); "t1"); t1.start();t2 = new thread(()log.debug(i + "\t" + classlayout.parseinstance(d).toprintable***true));locksupport.unpark(t3); "t2"); t2.start();t3 = new thread(()log.debug(i + "\t" + classlayout.parseinstance(d).toprintable***true));"t3"); t3.start();t3.join();log.debug(classlayout.parseinstance(new dog())toprintable***true));
@fork(1) @benchmarkmode(mode.**eragetime) @warmup(iterations=3) @measurement(iterations=5) @outputtimeunit(timeunit.nanoseconds) public class mybenchmark @benchmark public void b() throws exception }
j**a -jar benchmarks.jar
benchmark mode samples score score error units c.i.mybenchmark.a **gt 5 1.542 0.056 ns/op c.i.mybenchmark.b **gt 5 1.518 0.091 ns/opB有乙個鎖定的操作,那麼為什麼它與A和B所花費的時間幾乎不同呢?因為 J**A 中有乙個 JIT(just-in-time 編譯器),它會優化 **的重複執行,而 B 中的 O 物件根本不會被共享,所以在 B 中同步是沒有意義的,所以 J**A 會去掉鎖。 這個還有乙個開關,這個開關預設是開著的,下面的演示會把這個開關關掉。
j**a -xx:-eliminatelocks -jar benchmarks.jar
benchmark mode samples score score error units c.i.mybenchmark.a **gt 5 1.507 0.108 ns/op c.i.mybenchmark.b **gt 5 16.976 1.572 ns/op您可以看到所需的時間存在顯著差異。
多次鎖定同一物件,導致執行緒多次重入,可以使用鎖粗化進行優化,這與之前細分鎖的粒度不同。
作者:|老城區清道夫|
*:cnblogs.com/xiaoyh/p/17157540.html