<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在多執行緒中解決執行緒安全的問題時常用到Synchronized
,現在的synchronized相對於早期的synchronized做出了優化,從以前的加鎖就是重量級鎖優化成了有一個鎖升級的過程(偏向鎖->輕量級鎖->重量級鎖)。
cas的全稱是compare and swap,從名稱上可以看出它是先比較再進行設定,它是一種在多執行緒環境下實現同步功能的機制。
下面這段程式碼是在ReentrantLock類中複製的一段關於CAS操作的程式碼
protected final boolean compareAndSetState(int expect, int update) { // See below for intrinsics setup to support this return unsafe.compareAndSwapInt(this, stateOffset, expect, update); }
compareAndSwapInt的引數,這裡的引數一和引數二現在把他理解成是一個引數unsafe.compareAndSwapInt(curr, expect, update);
所以這一個Cas操作裡面需要三個引數
只有在當前值和期望值一致的時候才會將當前值修改成引數三所傳入的值。
CAS在JUC包中應用很廣泛,比如在AtomicXXX類中使用到了大量的CAS操作,
CAS不是很難理解,有個概念就好。
如果瞭解物件的記憶體佈局的可以略過此段。這個物件的記憶體佈局是和JVM的實現有關,本章所說的是HotSpot
的實現。
當一個物件被建立出來後它在記憶體中的佈局如下,由四部分組成:
看到上面的圖,應該可以大概的看出來synchronized加鎖,其實就是修改的對像頭裡面的markword的資料。所以synchronized可以對任何一個物件加鎖
現在有一個Java類T,將它new
出來之後它的物件的記憶體佈局是什麼樣子的呢?
class T{ Integer age; }
可以通過一個小工具來檢視下這個T類在記憶體中的物件佈局
<dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.9</version> <scope>compile</scope> </dependency>
通過下面的程式來列印下T物件的佈局是什麼樣子的。
public static void main(String[] args) { T o = new T(); System.out.println(ClassLayout.parseInstance(o).toPrintable()); }
這張圖是一個沒有加鎖的物件的物件佈局。
通過synchronized後的物件佈局是什麼樣子的呢?這次再修改下T類,目的是讓它存在位元組填充
class T{ Integer age; Integer age1; } public static void main(String[] args) { T o = new T(); synchronized (o){ System.out.println(ClassLayout.parseInstance(o).toPrintable()); } }
到這裡可能有些小夥伴有疑問,這裡為啥是輕量級鎖,不應該先是偏向鎖嗎?原因如下:
因為偏向鎖是有4秒的延遲的,所以如果想要看到效果可以在程式碼里加上sleep(4100)就可以了。或者是通過jvm引數-XX:BiasedLockingStartupDelay=0
將延遲設定成0
看完這裡也對markword有了些瞭解了,因為在synchronized中加鎖就是通過cas的方式修改的markword中的鎖狀態
上圖大概就是Synchronized加鎖後的一個鎖升級的過程。從早期的重量級鎖優化到了現在一個輕量級鎖。
上面的重量級鎖說到重量級鎖想要申請一把鎖需要使用者態到核心態的一個轉換,到了後期的JDK版本中,加鎖不用在去向OS去申請鎖了,只需要在使用者態就可以完成加鎖。
從名字上可以看出偏向鎖它就是偏向某一個執行緒,把這個鎖加到這個執行緒上,在加鎖的時候如果發現當前鎖的競爭執行緒只有一個執行緒的話,那麼這個鎖直接偏向這個執行緒。直接上鎖,不存在競爭。併線上程棧中建立一個LR(鎖記錄)並將markword拷貝到LR中,同時鎖中的markwrod中的指標也會指向當前持有鎖執行緒的LR
這裡的LR是有什麼作用?
首先synchronized是一個可重入鎖,它即然是一個可重入鎖它就得有一個東西用來記錄重入的次數(加鎖幾次必須解鎖幾次)。在解鎖時LR在棧中彈出一個就表示解鎖一次。
當有多個執行緒競爭的時候會升級成輕量級鎖(自旋鎖)
通過下圖來看下偏向鎖是怎麼一回事。
當大呆需要上WC時,只有它自已要上WC,此時並沒有其它的人需要上WC,那麼這時這個WC可以直接給大呆使用,並且大呆把可以標識自已身份的ID貼到門上,表示此時大呆佔用了這個WC。
當又有一個執行緒來搶佔鎖時發現當前鎖已被佔用,此時鎖會從偏向鎖升級成輕量級鎖。
匿名偏向
在執行的時候將偏向鎖的延遲設定成0-XX:BiasedLockingStartupDelay=0
public static void main(String[] args) throws InterruptedException { T o = new T(); System.out.println(ClassLayout.parseInstance(o).toPrintable()); }
可以看這個程式的執行結果,當前的鎖狀態是偏向鎖,而有意思是的鎖存在,但是他並沒有指向執行緒的指標,
這種情況稱為匿名偏向。
說到輕量級鎖可能需要在兩種情況下來說它,一是在升級成輕量鎖之前有偏向鎖,另一種是在升級輕量鎖之前沒有偏向鎖,這裡說完第一種第二種不用解釋各位也會明白是怎麼一回事。
還是用上面這個圖來解釋,此時當前的WC被大呆所佔用,這時二呆來了也要使用WC。這時大呆和二呆就要通過CAS的方式來搶佔WC。
因為此時鎖的狀態是偏向鎖的狀態,二呆來了也要使用WC(這時有兩個人同時要使用WC,這時就要將偏向鎖升級成輕量級鎖),在升級輕量鎖之前首先需要將WC上的標識大呆身份的ID撕下來(這一步叫做偏向鎖的復原),然後能過自旋+CAS的方式兩個人來搶鎖。當其中一個執行緒搶鎖成功後,會將LR貼到WC的門上,表示WC當前被某個執行緒佔用,然後另一個沒有搶到鎖的執行緒就一直自旋,當自旋一定次數後升級成重量級鎖。
如果在升級輕量鎖之前沒有偏向鎖,此時兩個執行緒直接自旋+CAS的方式來搶鎖。
在瞭解重量級鎖之前,我想應該先說下使用者態與核心態
:
對於系統而言,它可以做的一些事情,普通的應用程式是無法完成的,比如系統可以幹掉硬碟,如果普通的程式想要幹掉硬碟它必須向作業系統去申請,由此作業系統中的指令分了級別,作業系統級別可以存取所有的指令,在使用者態下只能存取使用者能存取的指令,如果使用者態要存取核心態可以執行的指令必須去向作業系統去申請,請作業系統呼叫。
在JDK早期,上鎖只能上重量級鎖。因為,所謂的JVM其實它也是工作在使用者態的一個程序,如果想要對一個物件進行上鎖,那它必須去向系統去申請鎖。申請鎖成功後,還需要將這把鎖從核心態返回到使用者態,它稱為重量級鎖的原因就是在鎖申請的時候都要有一個在使用者態到核心態的轉換。
當搶佔到鎖後,markword裡面記錄的不再是LR的指標,而是指向的是一個C++的物件ObjectMonitor,
如果當前執行緒自旋一段時間後沒有搶到鎖就會升級成重量級鎖,並將當前的執行緒存入EntryList佇列中阻塞,持有鎖的執行緒執行完成後,在喚醒EntryList佇列中的執行緒去搶佔鎖。
synchronized的鎖升級過程:
到此這篇關於Java中synchronized鎖升級的過程的文章就介紹到這了,更多相關synchronized鎖升級內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45