包裹地图的实现

时间:2013-07-06 12:09:49

标签: java multithreading collections

使用Collections.synchronizedCollection(map)包装地图有什么意义,如果那时你必须在迭代时同步代码?

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

包裹后,不应该是线程安全的吗?

3 个答案:

答案 0 :(得分:3)

  

使用Collections.synchronizedCollection(map)包装地图有什么意义,如果那时你必须在迭代时同步代码?

使单个操作具有线程安全性。 (就我个人而言,一般来说这不是一个坏主意,但这是另一回事。它并非毫无意义,只是有用性有限。)

  

包裹后,不应该是线程安全的吗?

对于任何个人操作,是的。但迭代涉及许多步骤 - 虽然每个步骤都将同步,但可以在步骤之间修改集合,使迭代器无效。不要忘记你的循环扩展到类似的东西:

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

如果您需要迭代是线程安全的,那么您应该使用java.util.concurrent中的一个集合...同时注意如果在迭代期间修改了集合则保证什么是不可用的警告

答案 1 :(得分:0)

包装之后,每个单独的方法都是线程安全的,但是迭代涉及重复调用方法(迭代器,然后是next和返回的Iterator上的hasNext),并且这些方法之间没有同步。这就是您需要同步迭代的原因。

您还需要使用同步集合(而不是仅仅围绕迭代代码进行同步),否则添加或删除项目的方法将不会同步,因此即使您使用同步块,也可以在迭代时进行修改。

答案 2 :(得分:0)

添加@ jonskeet的@jule的答案,你应该考虑使用ConcurrentHashMaphttp://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html),它不需要锁定迭代。