2011-08-01 99 views
2

我需要澄清關於javaron中同步關鍵字的工作原理。Java同步關鍵字 - 它是否保護類方法不被同時執行?

使用下面的示例類。現在

class Carrier { 

    private String[] _collection = new String[2]; 

    public Carrier() { 
     this._collection[0] = "abc"; 
     this._collection[1] = "123"; 
    } 

    public syncronized void change(int cId) { 
     Thread.sleep(3000); 
     this._collection[cId] = "changed"; 
    } 

} 

,在應用中的一些地方,它引用了運營商級的同一個對象實例中,.change()方法被調用時,有可能在同一時間。

...carrier.change(1); 

...

...carrier.change(1); 

請問syncronized關鍵字防止方法的asyncronized執行?它是否將呼叫排隊到.change(),等待每個人完成?

+0

'它會簡單地排隊呼叫。變化()'。取決於你排隊的意思。執行順序沒有指定,所以它不是一個有序隊列,但是,其他線程將被迫等待。 – Kaj

回答

2

是的,它會阻止兩個方法調用同時執行。

這確實是​​關鍵字的主要用途。

當一個同步方法運行時,它會在它所調用的對象上獲得'鎖定'。這意味着當該方法持有該鎖時,不能在該對象上運行其他同步代碼。一旦方法完成執行,它將釋放該鎖,並且其他同步方法可以獲取該對象上的鎖。

1

是的,是的。 (請注意它是​​,而不是syncronized

4

是的,第二個線程會在第一個線程執行時阻塞。這是因爲他們都試圖通過this獲取相同對象上的顯示器,在這種情況下。所以,你的change方法等效於:

public void change(int cId) { 
    synchronized (this) { 
     Thread.sleep(3000); 
     this._collection[cId] = "changed"; 
    } 
} 

我個人不喜歡上同步「這個」,因爲這意味着任何其他代碼訪問對象本身能獲得相同的顯示器。我希望創建一個對象只是爲鎖定其只有類內代碼可以訪問:

private final Object lock = new Object(); 

public void change(int cId) { 
    synchronized (lock) { 
     Thread.sleep(3000); 
     this._collection[cId] = "changed"; 
    } 
} 

這將仍然有兩個線程調用同一個對象上change方面同樣的效果,因爲兩個線程仍然會獲取相同的顯示器 - 只是與特定於鎖的對象關聯的顯示器。

+0

單獨鎖定對象上的優點。 – dropson

1

是 - synchronized關鍵字阻止不同線程同時執行該方法。

注意:「類方法」是一種static方法。你的問題中有一個「實例方法」(即非靜態)。

+0

太好了。我會將其添加到我的詞彙表中。與「正在」(不是beeing);-)一起 – dropson

1

​​用於防止同時訪問cuncurrent編程。 例如,當您需要客戶端,一個讀取,另一個寫入:

鎖定here的詳細解釋。