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