2013-07-06 63 views
2

如果您在迭代過程中必須同步代碼,那麼用Collections.synchronizedCollection(map)包裝地圖有什麼意義?包裹實施的地圖

Collection<Type> c = Collections.synchronizedCollection(myCollection); 
synchronized(c) { 
     for (Type e : c) 
      foo(e); } 

包好後不應該線程安全嗎?

回答

3

如果你在迭代過程中必須同步代碼,那麼用Collections.synchronizedCollection(map)包裝地圖有什麼意義呢?

使單個操作線程安全。 (我個人認爲這是一個不好的主意,但這是另一回事,它不是毫無意義的,只是用途有限而已)。

包裝後,不應該是線程安全的嗎?

對於任何個人手術,是的。但迭代涉及許多步驟 - 雖然每個步驟都將同步,但可以在之間修改集合,使迭代器失效。不要忘記,你的循環被擴展爲類似:

for (Iterator<Type> iterator = c.iterator(); iterator.hasNext();) { 
    Type e = iterator.next(); 
    ... 
} 

如果您需要迭代是線程安全的,你應該使用在java.util.concurrent的收藏之一......同時指出什麼是警告和如果在迭代期間修改了集合,則不能保證。

0

包裝它後,每個單獨的方法是線程安全的,但迭代涉及重複調用方法(迭代器,然後next和返回的Iterator上的hasNext),並且這些方法之間沒有同步。這就是爲什麼你需要同步你的迭代。

您還需要使用同步集合(而不是僅僅圍繞您的迭代代碼進行同步),否則添加或刪除項目的方法將不會同步,因此可能會在迭代時進行修改,即使您使用了同步塊。