摘要:第一個字被稱為。經量級鎖的加鎖過程當一個對象被鎖定時,被復制到當前嘗試獲取鎖的線程的線程棧的鎖記錄空間被復制的官方稱為。根據鎖對象目前是否處于被鎖定狀態(tài),撤銷偏向后恢復到未鎖定或經量級鎖定狀態(tài)。
Synchronized關鍵字
synchronized的鎖機制的主要優(yōu)勢是Java語言內置的鎖機制,因此,JVM可以自由的優(yōu)化而不影響已存在的代碼。
任何對象都擁有對象頭這一數(shù)據結構來支持鎖,但是對于較大的對象系統(tǒng)開銷會更大一些。
java中的每一個對象都至少包含2個字(24 Bytes for 32bits & 28 Bytes for 64bits, 不包括已壓縮的對象)。第一個字被稱為Mark Word。這是一個對象的頭,它包含了不同的信息,包括鎖的相關信息。
第二個字是指向metadata class的指針,metadata class字義了對象的類型。這部分也包含了VMT(Virtual Method Table)。
Mark Word 的結構如下所示:
Mark Word根據最低兩位(Tag)的所表示的狀態(tài),編碼了不同的信息。
如果這個對象沒有被用作鎖,Mark Word 記錄了hashcode和對象年齡(for GC/survivors)。
除此之外,有3種狀態(tài)對應鎖:輕量級鎖,重量級鎖和偏向鎖。
所有現(xiàn)代JVM都引入了經量級鎖:
避免將每個對象關聯(lián)操作系統(tǒng)的mutex/condition變量(重量級鎖)
當不存在鎖競爭時,使用原子操作來進入退出同步塊
如果發(fā)生鎖競爭,回退到操作系統(tǒng)的重量級鎖
引入輕量級鎖會提供鎖效率,因為大部分鎖都不存在競爭。
經量級鎖的加鎖過程:
當一個對象被鎖定時,mark word被復制到當前嘗試獲取鎖的線程的線程棧(Execution stack)的鎖記錄空間(lock record), 被復制的mark word官方稱為displaced mark。
使用CAS操作來嘗試使 mark word指向當前線程的鎖記錄空間(即在mark word中存入使用當前線程鎖記錄空間的指針——stack pointer)。
如果CAS操作成功,則線程獲得鎖。
如果CAS操作失敗,即表明存在鎖競爭,則發(fā)生鎖膨脹,回退到重量級鎖。
鎖記錄空間中記錄了被當前執(zhí)行方法鎖定的對象(通過遍歷線程棧找到線程的鎖對象)
經量級鎖加鎖前:
經量級鎖加鎖后:
經量級鎖的解鎖過程:
解鎖使用CAS來把displaced mark寫回對象的mark word中。
如果CAS失敗, 表示發(fā)生鎖競爭:則鎖膨脹。(通知其他等待線程鎖已釋放)
將鎖記錄空間置為0:如果發(fā)生鎖膨脹,則用0替換displaced mardk,如果不存在競爭,則CAS將鎖記錄空間置為0后,停止CAS操作。
偏向鎖偏向鎖的引入:
在多處理器上CAS操作可能開銷很大。
大多數(shù)鎖不僅不存在競爭,而且往往由同一個線程使用。
使多帶帶一個線程獲取鎖的開銷更低。
代價是使另一個線程獲取鎖開銷增大。
偏向鎖加鎖過程:
當鎖對象第一次被線程獲取時,VM把對象頭中的標志位設為101,即偏向模式。同時使用CAS把獲取到這個鎖的線程ID記錄在對象的mark word中,如果CAS成功,則持有偏向鎖的線程以后每次進行這個鎖相關的同步塊時,不再進行任務同步操作,只進行比較Mark word中的線程ID是否是當前線程的ID。
偏向鎖的解鎖過程:
當另外一個線程去嘗試獲取這個鎖時,偏向模式結束。根據鎖對象目前是否處于被鎖定狀態(tài),撤銷偏向后恢復到未鎖定或經量級鎖定狀態(tài)。
VM會停止持有偏向鎖的線程(實際上,VM不能停止單一線程,而是在安全點進行的操作)。
遍歷持有偏向鎖的線程的棧,找到鎖記錄空間,將displaced mark 寫入到最舊的鎖記錄空間,其他的寫0。
更新鎖對象的mark word。如果被鎖定,則指向最舊的鎖記錄空間,否則,填入未鎖定值。
偏向鎖的特點:
偏向于第一個獲取鎖的線程:
在mark word的Tag中增加一位
001表示無鎖狀態(tài)
101表示偏向或可偏向狀態(tài)(thread ID ==0 == unlock)
通過CAS來獲取偏向鎖
對于持有鎖的線程接下的鎖獲取和釋放開銷非常小(僅僅判斷下,不需要CAS同步操作)。
如果另一個線程鎖定了偏向鎖對象,則偏向鎖收回,升級為輕量級鎖(增加了另一個線程獲取鎖的開銷)。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66060.html
摘要:基礎問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關鍵字修飾符知識點總結必看篇中的關鍵字解析回調機制解讀抽象類與三大特征時間和時間戳的相互轉換為什么要使用內部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點及比較提高篇八詳解內部類單例模式和 Java基礎問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關鍵字修飾符知識點總結必看篇中的關鍵字解析回調機制解讀抽象類與三大特征時間和時間戳的相互轉換為什么要使用內部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點及比較提高篇八詳解內部類單例模式和 Java基礎問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關鍵字修飾符知識點總結必看篇中的關鍵字解析回調機制解讀抽象類與三大特征時間和時間戳的相互轉換為什么要使用內部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點及比較提高篇八詳解內部類單例模式和 Java基礎問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:線程通過的方法獲得鎖,用方法釋放鎖。和關鍵字的區(qū)別在等待鎖時可以使用方法選擇中斷,改為處理其他事情,而關鍵字,線程需要一直等待下去。擁有方便的方法用于獲取正在等待鎖的線程。 ReentrantLock是Java并發(fā)包中一個非常有用的組件,一些并發(fā)集合類也是用ReentrantLock實現(xiàn),包括ConcurrentHashMap。ReentrantLock具有三個特性:等待可中斷、可實現(xiàn)...
閱讀 875·2021-09-02 09:55
閱讀 1503·2019-12-27 12:02
閱讀 1692·2019-08-30 14:24
閱讀 1142·2019-08-30 14:18
閱讀 2755·2019-08-29 13:57
閱讀 2200·2019-08-26 11:51
閱讀 1369·2019-08-26 10:37
閱讀 769·2019-08-23 16:09