Java併發之synchronized關鍵字深度解析(一)
前言
近期研讀路神之絕世武學,徜徉於浩瀚無垠知識之海洋,偶有攫取吉光片羽,惶恐未領略其精髓即隱入歲月深處,遂急忙記錄一二,順備來日吹cow之談資。本小系列為併發之親兒子-獨臂狂俠synchronized專場。
一、使用場景
synchronized是java中的一個關鍵字,用於給物件加鎖,保證在單機的併發條件下執行緒安全。原子性和可見性是它保證執行緒安全的基礎功能。一定要注意它鎖的是物件,而且它是一個排他的非公平可重入鎖。本文先從使用的場景上來展現其作用。
1、用在普通方法中
常用的格式如下所示:
1 public static void main(String[] args) { 2 Object obj = new Object(); 3 synchronized (obj) { 4 System.out.println("進入鎖"); 5 // 邏輯略去 6 System.out.println("退出鎖"); 7 } 8 }
其中obj就是我們加鎖的物件,同一個物件,同一刻只能由一個執行緒加鎖,即同一個物件的多個同步塊,只能順序執行,無法同時並行執行。
2、用在普通方法上
如下所示:
1 public synchronized void lockMethod () { 2 System.out.println("進入鎖"); 3 // 邏輯略去 4 System.out.println("退出鎖"); 5 }
用在普通方法上時,無需指定鎖的物件,這種情況下java預設鎖的是當前的例項物件。效果類似於1中,小括號裡面是this。
3、用在靜態方法上
如下所示:
1 public synchronized static void lockMethod () { 2 System.out.println("進入鎖"); 3 // 邏輯略去 4 System.out.println("退出鎖"); 5 }
這種情況下,synchronized鎖的是當前的類物件,此時形成全域性鎖,即在同一個JVM中,用到此方法的地方都是挨個執行此方法。
二、synchronized鎖的往事
大家對JUC包中的lock鎖應該都有過了解,它是jdk1.5的時候出現的,剛出來時lock鎖的效能全方位碾壓synchronized鎖。但synchronized作為Java的嫡系子孫,JVM的開發者們肯定要不遺餘力地扶持它,所以在jdk1.6中針對synchronized做了很多的優化,使其效能跟lock鎖相差無幾,親兒子不愧是親兒子。在jdk1.6中,synchronized會分不同情況對程式碼的加鎖機制做優化,比如分了三種鎖:偏向鎖、輕量級鎖、自旋鎖、重量級鎖,設定了鎖膨脹策略、鎖清除機制,還做了批量重偏向、偏向鎖批量撤銷等實現方式提高同步塊執行效率。後面我會用兩節對其原理進行介紹。
三、後記
何之謂獨臂狂俠,蓋因發功之時,僅需單臂一刀(引用一次),無需左手加鎖右手放鎖,而這一刀之功力,便可覆蓋周身八丈,渾然天成,勁氣運轉之時水潑不進,幾近無法可破。
&n