Collections.synchronizedCollection(map)
如果在迭代时必须同步代码,那么用 包装地图有什么意义?
Collection<Type> c = Collections.synchronizedCollection(myCollection);
synchronized(c) {
for (Type e : c)
foo(e); }
包装好后,不应该是线程安全的吗?
Collections.synchronizedCollection(map)
如果在迭代时必须同步代码,那么用 包装地图有什么意义?
Collection<Type> c = Collections.synchronizedCollection(myCollection);
synchronized(c) {
for (Type e : c)
foo(e); }
包装好后,不应该是线程安全的吗?
如果在迭代时必须同步代码,那么用 Collections.synchronizedCollection(map) 包装地图有什么意义?
使单个操作线程安全。(我个人认为总的来说这是一个坏主意,但那是另一回事。这不是没有意义的,只是有用性有限。)
包装好后,不应该是线程安全的吗?
对于任何单独的操作,是的。但是迭代涉及许多步骤 - 虽然每个单独的步骤都将同步,但可以在步骤之间修改集合,从而使迭代器无效。不要忘记您的循环已扩展为:
for (Iterator<Type> iterator = c.iterator(); iterator.hasNext(); ) {
Type e = iterator.next();
...
}
如果您需要迭代是线程安全的,则应使用java.util.concurrent
... 中的集合之一,同时注意有关在迭代期间修改集合是否保证的警告。
包装之后,每个单独的方法都是线程安全的,但是迭代涉及重复调用方法(迭代器,然后是返回的迭代器上的下一个和 hasNext),并且这些方法之间没有同步。这就是您需要同步迭代的原因。
您还需要使用同步集合(而不仅仅是围绕迭代代码进行同步),因为否则添加或删除项目的方法将不会同步,因此即使您使用了同步块,也可能在迭代时进行修改。
添加到@jonskeet 的@jule 的答案,您应该考虑使用不需要锁定迭代的ConcurrentHashMap
(http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html )。