2016-09-27 128 views
3

如果我有這樣的事情snippet-同步同步列表

public List<E> list = Collections.synchronizedList(new ArrayList<E>()); 

然後,如果我做的方法中的一些操作 -

boolean absent = !list.contains(x);    // Statement 1 
if(absent)          // Statement 2 
    list.add(x);        // Statement 3 

做我需要包裝內synchronized(list){ ... }上述語句進行操作atomic

+1

我不認爲這個問題是鏈接給出的倍數。這一個請求同步列表中的代碼塊,而另一個則是同步單個方法調用。即使他們的答案是不同的(必要的,而不是其他的)。 – uoyilmaz

+1

@uoyilmaz這是一個規範,涵蓋了使用'synchronized'和'synchronizedList'方法的用例。和[answers](http://stackoverflow.com/a/9468329/1743880)也涵蓋了這一點:*如果該塊在列表上執行多個操作[...],那麼同步並不是多餘的* – Tunaki

回答

3

我是否需要將上述語句包裝到synchronized(list){ ... }以使操作原子化?

是否則你的List可以調用containsadd的時間窗口可能導致競爭條件問題內你的代碼的其他地方進行修改。

它使我的事情然後有什麼用 Collections.synchronizedList

Collections.synchronizedList讓您的List線程安全的,這樣你可以同時修改,但仍然是所有方法調用自動執行。在上面的情況下,您需要撥打containsadd您必須以原子方式執行,否則如果其他地方我們稱addcontains的結果可能會過時,這將導致競爭條件問題。防止競爭狀態問題的唯一方法是在您的案例中使用list相同的對象監視器上的同步塊。

+0

它使我那麼想想Collections.synchronizedList的用法是什麼? –

+0

@ShirgillFarhanAnsari假設兩個線程並行調用remove()。如果你的基礎列表不同步,有趣的事情會發生。重點是防止**獨立**更改並行發生同步列表時發生問題。你正在談論一組「呼之欲出」的電話! – GhostCat

+1

感謝您的幫助。我碰巧看到你的個人資料。你就像我一樣認爲這是JEE。它從來沒有/是JEE。我的JavaEE正在由Web應用專家BalusC(JSF 2.3專家組成員)糾正。 –

1

正確。理論上,你的陳述1和3之間可能會發生任何事情;因此:如果你想讓它們發生「原子」;那麼你需要一些把它們變成「單筆交易」的方式。

使用synchronized(list)是一種合理的方法。

2

是的,同步列表使得方法調用是原子的,但是如果你想讓多個語句成爲原子的話(例如,當遍歷列表等)時,你需要同步訪問。