摘要:是如何加鎖的從字節(jié)碼層面看生了個(gè)字節(jié)碼命令代表進(jìn)入代表退出從層面看問題一的鎖信息存放在哪里的鎖信息存放在對象頭中。對象頭中包含個(gè)部分示例數(shù)據(jù)存放對象的字段內(nèi)容中包含了鎖的標(biāo)記位。線程不會(huì)被掛起。重量級鎖線程會(huì)被掛起,會(huì)被切換出去。
1、synchronized 關(guān)鍵字的鎖對象是誰?
①當(dāng)synchronized 關(guān)鍵字加在實(shí)例方法上,那么鎖對象是當(dāng)前類實(shí)例
示例代碼
synchronized void a() { try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("a"); } synchronized void b() { System.out.println("b"); } public static void main(String[] args) { ThreadTest test = new ThreadTest(); new Thread(() -> { test.b(); }).start(); new Thread(() -> { test.a(); }).start(); }
②、當(dāng)synchronized 關(guān)鍵字加在靜態(tài)方法上,那么鎖對象是當(dāng)前類
示例代碼
static synchronized void a() { System.out.println("aaaa"); try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("a"); } static synchronized void b() { System.out.println("b"); } public static void main(String[] args) { ThreadTest test = new ThreadTest(); ThreadTest test1 = new ThreadTest(); new Thread(() -> { ThreadTest.a(); }).start(); new Thread(() -> { ThreadTest.b(); }).start(); }
2、synchronized 關(guān)鍵字可重入嗎?
synchronized 是可重入的!
示例代碼
synchronized void a() { System.out.println("aaaa"); b(); try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("a"); } synchronized void b() { System.out.println("b"); } public static void main(String[] args) { ThreadTest test = new ThreadTest(); test.a(); }
a方法中調(diào)用b方法。因?yàn)楫?dāng)前的鎖對象是類的實(shí)例,調(diào)用a方法時(shí),可以立馬調(diào)用b方法,說明sychronized是可重入的。
3、synchronized是如何加鎖的?
①從字節(jié)碼層面看
Jvm 生了2個(gè)字節(jié)碼命令
monitorenter代表進(jìn)入
monitorexit代表退出
②從jvm層面看
問題一:synchronized的鎖信息存放在哪里?
synchronized 的鎖信息存放在對象頭中。
對象頭中包含2個(gè)部分
1、MarkDown
2、示例數(shù)據(jù)(存放對象的字段內(nèi)容)
MarkDown 中包含了鎖的標(biāo)記位。
其中鎖有偏向鎖,輕量級鎖,重量級鎖。
3者的使用場景如下:1個(gè)線程進(jìn)入臨界區(qū),多個(gè)線程交替進(jìn)入臨界區(qū),多個(gè)線程同時(shí)進(jìn)入臨界區(qū)
偏向鎖
只有1個(gè)線程進(jìn)入臨界區(qū),線程獲取鎖之后,不會(huì)釋放鎖,再次進(jìn)入的時(shí)候無需再次加鎖
輕量級鎖
多個(gè)線程交替進(jìn)入臨界區(qū),以自旋的方式進(jìn)行忙循環(huán)。線程不會(huì)被掛起。也就是線程不會(huì)被切換出去。
重量級鎖
線程會(huì)被掛起,會(huì)被切換出去。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/76679.html
摘要:三關(guān)鍵字能保證原子性嗎并發(fā)編程藝術(shù)這本書上說保證但是在自增操作非原子操作上不保證,多線程編程核心藝術(shù)這本書說不保證。多線程訪問關(guān)鍵字不會(huì)發(fā)生阻塞,而關(guān)鍵字可能會(huì)發(fā)生阻塞關(guān)鍵字能保證數(shù)據(jù)的可見性,但不能保證數(shù)據(jù)的原子性。 系列文章傳送門: Java多線程學(xué)習(xí)(一)Java多線程入門 Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)synchroniz...
摘要:轉(zhuǎn)載請備注地址多線程學(xué)習(xí)二將分為兩篇文章介紹同步方法另一篇介紹同步語句塊。如果兩個(gè)線程同時(shí)操作對象中的實(shí)例變量,則會(huì)出現(xiàn)非線程安全,解決辦法就是在方法前加上關(guān)鍵字即可。 轉(zhuǎn)載請備注地址: https://blog.csdn.net/qq_3433... Java多線程學(xué)習(xí)(二)將分為兩篇文章介紹synchronized同步方法另一篇介紹synchronized同步語句塊。系列文章傳送門...
摘要:關(guān)鍵字加到非靜態(tài)方法上持有的是對象鎖。線程和線程持有的鎖不一樣,所以和運(yùn)行同步,但是和運(yùn)行不同步。所以盡量不要使用而使用參考多線程編程核心技術(shù)并發(fā)編程的藝術(shù)如果你覺得博主的文章不錯(cuò),歡迎轉(zhuǎn)發(fā)點(diǎn)贊。 系列文章傳送門: Java多線程學(xué)習(xí)(一)Java多線程入門 Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(2) J...
摘要:運(yùn)行可運(yùn)行狀態(tài)的線程獲得了時(shí)間片,執(zhí)行程序代碼。阻塞的情況分三種一等待阻塞運(yùn)行的線程執(zhí)行方法,會(huì)把該線程放入等待隊(duì)列中。死亡線程方法執(zhí)行結(jié)束,或者因異常退出了方法,則該線程結(jié)束生命周期。死亡的線程不可再次復(fù)生。 系列文章傳送門: Java多線程學(xué)習(xí)(一)Java多線程入門 Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)synchronized關(guān)鍵...
摘要:的內(nèi)置鎖是一種互斥鎖,意味著最多只有一個(gè)線程能持有這種鎖。使用方式如下使用顯示鎖之前,解決多線程共享對象訪問的機(jī)制只有和。后面會(huì)陸續(xù)的補(bǔ)充并發(fā)編程系列的文章。 早期的計(jì)算機(jī)不包含操作系統(tǒng),它們從頭到尾執(zhí)行一個(gè)程序,這個(gè)程序可以訪問計(jì)算機(jī)中的所有資源。在這種情況下,每次都只能運(yùn)行一個(gè)程序,對于昂貴的計(jì)算機(jī)資源來說是一種嚴(yán)重的浪費(fèi)。 操作系統(tǒng)出現(xiàn)后,計(jì)算機(jī)可以運(yùn)行多個(gè)程序,不同的程序在單獨(dú)...
閱讀 3026·2021-10-14 09:42
閱讀 3811·2021-08-11 11:19
閱讀 3616·2019-08-30 13:57
閱讀 3215·2019-08-30 13:49
閱讀 1612·2019-08-29 18:38
閱讀 963·2019-08-29 13:16
閱讀 1912·2019-08-26 13:25
閱讀 3296·2019-08-26 13:24