摘要:是如何加鎖的從字節碼層面看生了個字節碼命令代表進入代表退出從層面看問題一的鎖信息存放在哪里的鎖信息存放在對象頭中。對象頭中包含個部分示例數據存放對象的字段內容中包含了鎖的標記位。線程不會被掛起。重量級鎖線程會被掛起,會被切換出去。
1、synchronized 關鍵字的鎖對象是誰?
①當synchronized 關鍵字加在實例方法上,那么鎖對象是當前類實例
示例代碼
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(); }
②、當synchronized 關鍵字加在靜態方法上,那么鎖對象是當前類
示例代碼
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 關鍵字可重入嗎?
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方法中調用b方法。因為當前的鎖對象是類的實例,調用a方法時,可以立馬調用b方法,說明sychronized是可重入的。
3、synchronized是如何加鎖的?
①從字節碼層面看
Jvm 生了2個字節碼命令
monitorenter代表進入
monitorexit代表退出
②從jvm層面看
問題一:synchronized的鎖信息存放在哪里?
synchronized 的鎖信息存放在對象頭中。
對象頭中包含2個部分
1、MarkDown
2、示例數據(存放對象的字段內容)
MarkDown 中包含了鎖的標記位。
其中鎖有偏向鎖,輕量級鎖,重量級鎖。
3者的使用場景如下:1個線程進入臨界區,多個線程交替進入臨界區,多個線程同時進入臨界區
偏向鎖
只有1個線程進入臨界區,線程獲取鎖之后,不會釋放鎖,再次進入的時候無需再次加鎖
輕量級鎖
多個線程交替進入臨界區,以自旋的方式進行忙循環。線程不會被掛起。也就是線程不會被切換出去。
重量級鎖
線程會被掛起,會被切換出去。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76679.html
摘要:三關鍵字能保證原子性嗎并發編程藝術這本書上說保證但是在自增操作非原子操作上不保證,多線程編程核心藝術這本書說不保證。多線程訪問關鍵字不會發生阻塞,而關鍵字可能會發生阻塞關鍵字能保證數據的可見性,但不能保證數據的原子性。 系列文章傳送門: Java多線程學習(一)Java多線程入門 Java多線程學習(二)synchronized關鍵字(1) java多線程學習(二)synchroniz...
摘要:轉載請備注地址多線程學習二將分為兩篇文章介紹同步方法另一篇介紹同步語句塊。如果兩個線程同時操作對象中的實例變量,則會出現非線程安全,解決辦法就是在方法前加上關鍵字即可。 轉載請備注地址: https://blog.csdn.net/qq_3433... Java多線程學習(二)將分為兩篇文章介紹synchronized同步方法另一篇介紹synchronized同步語句塊。系列文章傳送門...
摘要:關鍵字加到非靜態方法上持有的是對象鎖。線程和線程持有的鎖不一樣,所以和運行同步,但是和運行不同步。所以盡量不要使用而使用參考多線程編程核心技術并發編程的藝術如果你覺得博主的文章不錯,歡迎轉發點贊。 系列文章傳送門: Java多線程學習(一)Java多線程入門 Java多線程學習(二)synchronized關鍵字(1) java多線程學習(二)synchronized關鍵字(2) J...
摘要:運行可運行狀態的線程獲得了時間片,執行程序代碼。阻塞的情況分三種一等待阻塞運行的線程執行方法,會把該線程放入等待隊列中。死亡線程方法執行結束,或者因異常退出了方法,則該線程結束生命周期。死亡的線程不可再次復生。 系列文章傳送門: Java多線程學習(一)Java多線程入門 Java多線程學習(二)synchronized關鍵字(1) java多線程學習(二)synchronized關鍵...
摘要:的內置鎖是一種互斥鎖,意味著最多只有一個線程能持有這種鎖。使用方式如下使用顯示鎖之前,解決多線程共享對象訪問的機制只有和。后面會陸續的補充并發編程系列的文章。 早期的計算機不包含操作系統,它們從頭到尾執行一個程序,這個程序可以訪問計算機中的所有資源。在這種情況下,每次都只能運行一個程序,對于昂貴的計算機資源來說是一種嚴重的浪費。 操作系統出現后,計算機可以運行多個程序,不同的程序在單獨...
閱讀 2937·2021-10-14 09:42
閱讀 3702·2021-08-11 11:19
閱讀 3548·2019-08-30 13:57
閱讀 3130·2019-08-30 13:49
閱讀 1542·2019-08-29 18:38
閱讀 902·2019-08-29 13:16
閱讀 1859·2019-08-26 13:25
閱讀 3233·2019-08-26 13:24