Java synchronized是如何工作的

1. 爲什麼需要synchronization

Java是多線程的編程語言, 所以對java對象或者java class進行同步是非常重要的。 在java中實現同步的方法可以採用java 關鍵字synchronized或者 violate

在java多線程的環境中, 也不是所有的東西都需要synchronization. 比如, 如果共享的對象是可變的, 那是需要同步的;如果共享的對象是隻讀的或者是不可變的對象, 那就不需要使用同步的技術。

這個同步是由JVM來保證的.

 

2. synchronized方法與synchronized塊

這兩種方法都可以實現對java對象的同步。

先來看synchronized方法, 1) 它可以提供共享資源的互斥訪問, 避免數據競爭。 2)可以防止代碼被編譯器進行reordering, 而造成的併發問題。 3)提供lock與unlock的方法, 在進入要同步的地方之前,要先獲得lock,從而在memory中讀取東西, 在釋放lock的時候, 再把數據寫回memory.

 

再來看synchronized block, 它不是對整個對象或者類進行lock,而是隻針對特定的部分進行同步lock, 而對其他不需要同步的地方, 允許併發訪問與執行, 這樣可以加快系統的效率。

 

所以強烈推薦使用synchronized block

3. synchronized的粒度

下面這個例子, 實際上沒有起到同步的效果。

public class Counter{
private static count = 0;

public static synchronized  getCount(){
  return this.count;
}

public synchoronized setCount(int count){
   this.count = count;
}

}


getCount是對類Coutner.class的鎖定, 而setCount是對對象(this)的鎖定。 所以他們可以併發的進行, 從而造成對count值的設置與讀取有問題。

 

 

4. 使用synchronized的關鍵點

 

1) synchronized關鍵定只是用來提供在多線程環境中對java共享資源的互斥訪問。 它保證了使用相同鎖的多個線程的同步問題,

2) synchronized 關鍵定只能用在synchronized方法或者synchronized 塊中,不能對變量進行synchronized操作

3) 當線程進入 synchronized時, 它必須獲得相應的鎖, 而當它離開時, 要釋放對應的鎖。 鎖會在線程完成同步或者是出現錯誤或異常時釋放。

4) 當Java Thread進行一個syncrhonized 的Java 方法時, 會要求獲得對象級別的鎖;而當進入Static synchronized方法時, 需要獲得類級別的鎖。

5) Java Synchronized關鍵字是可以重入的。

6) 如果java synchronized 塊同步的對象是null的話, JAVA會拋出NullPointerException異常。

7) synchronized只能在同一個JVM上實現同步。 

8) 使用synchronized會造成performance的下降。

9) Java synchronized block要優於synchronized method

10) 在Java5之後, 使用violate的變量都是原子的。

11) synchronized 不能用在構造函數中, 它會造成編程的錯誤。

12) synchronized 不能用變量上

13) Java類庫Calendar 和SimpleDataFormat不是線程安全的, 所以 需要另外的同步機制。

 

發佈了72 篇原創文章 · 獲贊 4 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章