2011-02-05 231 views
2

使用現有的同步Java類(Hashtable中,StringBuffer的,矢量)同步的業務邏輯

當我們執行非同步Java類同步塊實施的執行情況(HashMap的,StringBuilder的,ArrayList中)

創建同步的集合OB從Collections.synchronizedXXX()方法中使用它,然後使用它(當然,我不能同步StringBuilder這樣。!!)

在多線程場景中,以上哪一種將是實現同步的最佳方法沒有任何表現殺人?

在此先感謝。

+1

StringBuilder未同步,StringBuffer已同步。 – pingw33n 2011-02-05 07:55:47

+0

感謝您使它注意到.. +1爲你..! – 2011-02-05 08:22:56

回答

2

最好的方法取決於你的代碼試圖做什麼以及你需要的原子級別。有時Collections.synchronizedWhatever是好的;有時你需要做自己的同步。

就性能而言,您只需確保最大限度地減少輸入的​​塊的數量即可。會有差別不大

之間

(example A) 
List l = Collections.synchronizedList(originalList); 
l.add(something); 

(example B) 
synchronized (originalList) { 
    originalList.add(something); 
} 
,因爲它們都進入一個synchronized塊。但是:

(example C) 
List l = Collections.synchronizedList(originalList); 
l.add(something); 
int index = l.indexOf(something); 

將進入兩個同步塊,而

(example D) 
synchronized (originalList) { 
    originalList.add(something); 
    int index = originalList.indexOf(something); 
} 

將僅輸入一個同步塊。當然,它在該塊中花費更長的時間,因此它可能會增加爭用,但add和indexOf現在表現得像一個單一的原子操作。這可能是也可能不是你想要的:它完全取決於應用程序。

編輯:爲了回答Deepak的問題:

在「synchronizedList」例如以C表示,每個呼叫對「L」的方法將一個同步塊內纏繞。你可以認爲C爲這樣:

synchronized (originalList) { 
    originalList.add(something); 
} 
synchronized (originalList) { 
    int index = originalList.indexOf(something); 
} 

這裏有一些額外的成本,但除非它在你的代碼的性能關鍵部分它可能不會是一個問題。我建議你在考慮優化代碼之前先考慮更多關於確保代碼正確運行的信息。很難讓線程安全的代碼正確,所以要非常小心你寫的東西。例如,在C中,'l.add(something)'和'l.indexOf(something)'之間可能存在競爭條件。 D沒有相同的競爭條件,因爲這兩個操作都在一個同步塊內。

Brian Goetz的書(Java Concurrency in Practice)是學習如何編寫線程安全代碼的極好資源。我強烈推薦它。我確定它在亞馬遜上。