首頁  >  文章  >  Java  >  Java中synchronized關鍵字的用法介紹(程式碼範例)

Java中synchronized關鍵字的用法介紹(程式碼範例)

不言
不言轉載
2019-01-30 11:21:013707瀏覽

這篇文章帶給大家的內容是關於Java中synchronized關鍵字的用法介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

在並發程式設計中,synchronized關鍵字是常出現的角色。之前我們都稱呼synchronized關鍵字為重量鎖,但是在JDK1.6中對synchronized進行了優化,引入了偏向鎖、輕量鎖。本篇介紹synchronized關鍵字的使用方式,區別和偏向鎖、輕量鎖定和重量鎖定實現原理。

先看看synchronized關鍵字的4種用法。

1、修飾普通方法

#
private synchronized void synMethod(){
}

這種用法中, synchronized鎖的物件實例。

2、修飾靜態方法

private static synchronized void synMethod(){
}

synchronized在這種情況下,鎖的是目前Class類別物件。

3、同步方法區塊

private  void synMethod1(){
        synchronized(this){
            
        }
    }    
    private  void synMethod2(){
        synchronized(ThreadTest.class){
            
        }
    }

synMethod1中鎖定物件實例;synMethod2的是當前Class類別物件。

再介紹鎖定原理

在介紹鎖定原理之前,先認識Java物件頭Mark Word,以32位元為例。

上面的表格中,描述的是物件在每個鎖定狀態時,物件頭中所儲存的資訊。

1、偏向鎖定

在實際環境中,執行緒在存取同步區塊時,如果沒有其他執行緒對鎖定進行競爭,並且由同一個線程多次獲得鎖,也就是單線程運行同步程式碼,在這種情況下,若是每次還阻塞線程,就代表白白浪費CPU效能。在這種情況下,引入了偏向鎖定概念。

  • #存取同步程式碼區塊

  • 判斷物件頭Mark Word中儲存的線程ID是否指向目前線程,如果是,則表示目前是鎖的重入,不需要再取得鎖,直接執行同步程式碼

  • 如果不是,則嘗試使用CAS演算法將執行緒ID更新到物件頭中。

  • 成功,取得鎖,執行同步程式碼。更新失敗表示存在鎖定競爭,等待全域安全點,暫停擁有偏向鎖定的線程,根據物件頭的鎖定標誌位,選擇將偏向鎖定升級為輕量鎖定或置為無鎖定。

  可以使用-XX:-userBiasedLocking=false來關閉JVM偏向鎖定最佳化,預設直接進入輕量級鎖定。

2、輕量鎖定

 

  • 存取同步程式碼區塊時,先在目前執行緒的執行緒堆疊中建立一個鎖定記錄(Lock Record)區域。

  • 把物件頭Mark Word拷貝到Lock Record中。

  • 利用CAS嘗試將物件頭Mark Word中的線程指標更新為指向當前線程的指標

  • 更新成功,則獲得輕量級鎖。

  • 更新失敗,檢查Mark Word中的指標是否指向目前執行緒。

  • 如果是,則表示是鎖的重入現象。執行同步程式碼區塊

  • 如果不是,則表示此時存在競爭。需要把輕鎖膨脹為重量鎖。

3、重量鎖

重量鎖是基於物件監視器(Monitor)來實現的。

執行緒在執行同步程式碼時,需要呼叫一個Monitor.enter指令。執行退出後,呼叫Monitor.exit指令。這裡看得出,監視器具有排它性,一個時間點只能有一個執行緒enter成功,其他執行緒只能阻塞在佇列中。所以這種重量鎖的操作成本很高。

已鎖定狀態

25 bit

4bit

#1bit

2bit

#

 

23bit

2bit

#是否偏向鎖定

鎖定標誌位元

#輕量級鎖定

指向堆疊中鎖定記錄的指標

#0

重量級鎖定

#

指向互斥量(重量級鎖定)的指標

10

GC標記

##11

#偏向鎖定

########線程######ID#####################Epoch##### #############物件分代年齡#######

1

01

無鎖定

物件的hashCode

##物件分代年齡

#0

01

以上是Java中synchronized關鍵字的用法介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除