使用Collections.synchronizedCollection(map)
包装地图有什么意义,如果那时你必须在迭代时同步代码?
Collection<Type> c = Collections.synchronizedCollection(myCollection);
synchronized(c) {
for (Type e : c)
foo(e); }
包裹后,不应该是线程安全的吗?
答案 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的答案,你应该考虑使用ConcurrentHashMap
(http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html),它不需要锁定迭代。