最近寫程式遇到各個 Thread 之間共用資料保護的問題,做了點功課,寫下一些小筆記。

簡單介紹

Synchronized使用時,需指定一個物件,系統會Lock此物件,當程式進入Synchrnoized區塊或Method時,該物件會被Lock,直到離開Synchronized時才會被釋放。在Lock期間,鎖定同一物件的其他Synchronized區塊,會因為無法取得物件的Lock而等待。待物件Release Lock後,其他的Synchronized區塊會有一個取得該物件的Lock而可以執行。

各種用法

1. Synchronized Method

synchrnoized public void syncMethod() {

}

此種synchronized用法鎖定的物件為Method所屬的物件,只要物件被new出超過一個以上的Instance,就有可能保護不到Method內程式。但如果此物件只會被new出一個Instance,譬如new出來後就放到ServletContext,要用的時候從ServletContext中拿出來執行,就可以避免此情況。

2. Synchronized Static Method

synchrnoized static public void syncMethod() {

}

此種synchronized用法鎖定的物件為Method所屬的物件的Class,不管被new出幾個的Instance,都能夠保證同一個時間只會有一個Thread在執行此Method。

3. Synchronized(this)

public void syncMethod() {
  synchronized(this) {
    …
  }
}

此種synchronized用法與synchronized method用法一樣,都是鎖定Method所屬的物件本身。

4. Synchronized(SomeObject)

public void syncMethod() {
  synchronized(SomeObject) {
    …
  }
}

此種synchronized用法鎖定的是SomeObject,如果SomeObject是同一個Class的兩個不同Instance,那synchronized區塊內就有可能被同時執行。如果每一個Synchronized的SomeObject都是同一個Instance(或者SomeObject本身就是Static),就可以保證區塊內同時間只會有一個Thread執行。

當使用Synchornized(SomeObject)時,SomeObject本身處於被Lock狀態,但此時其他的Thread是可以去更改SomeObject裡面的值,Lock只是同步化的狀態,不表示不能更改資料。

使用時機

Synchronized的使用時機很難定義,比較常見的情況是,當程式中會取出某一個共用的物件且會判斷物件內容值,再更新物件內容,此情況大部分都需要synchronized保護。

 

狼翔月影 發表在 痞客邦 PIXNET 留言(0) 人氣()