1. 程式人生 > >Java併發之synchronized關鍵字深度解析(一)

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