2010年7月21日 星期三

Java synchronized

簡單介紹

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保護。

=====================

Java synchronized概念

假設有一排餐廳,他們的編號從1...到無限大 ,每間餐廳都通過Restaurant標準,因此都能提供某些固定的服務。
每間餐廳都擁有一些一般區域與一個預約包廂,一般區域可以讓任意數量的人通行;而包廂只能同時讓一個人使用,若是有多於一個人要用,第一個進入包廂的人會將門鎖上,因此其他要進去的人就無法進入了,另外。
而這些餐廳共用一間豪華廁所,也是一次只能容納一個顧客,若廁所中已經有人,則後到者要等待。

在此例子,每個物件與 Java術語的對應關係是:

* 餐廳標準Restaurant:Class Restaurant
* 餐廳1號:Instance 1 of Restaurant
* 每間餐廳的一般區域:Normal Methods of Instance Restaurant
* 每間餐廳的包廂:Synchronized Methods of Instance Restaurant
* 顧客:Thread
* 所有餐廳共用的豪華廁所:Synchronized Static Methods of Class Restaurant

另外,所謂的包廂,指的是一組房間,因此所有被設定為synchronized的method都算在同一組包廂內。

1.現在若有兩人想要使用同一個餐廳的包廂,後到者B會被檔在門外,而先到者A可以進入包廂並任意使用其中的任何房間,B必須呆呆等到A離開這個包廂,或者A自願進入一間等待室,讓B進入。

在此例中,Thread A呼叫了餐廳instance r1的synchronized method m1();且Thread B隨後呼叫r1的另一個synchronized method m2();則B被阻擋,直到A離開m1()或者A執行了r1的wait()為止。

2.另一例子,若A進入包廂,但B在一般區域活動是沒有問題的,B並不會受到阻擋。

沒有留言:

張貼留言