在Java文档中,它说必须在迭代中再次手动同步同步集合。这是为什么?由于返回的集合已经同步。不太明白为什么会这样。谢谢。
Collection c = Collections.synchronizedCollection(myCollection);
...
synchronized(c) {
Iterator i = c.iterator(); // Must be in the synchronized block
while (i.hasNext())
foo(i.next());
}
答案 0 :(得分:3)
仅同步各个方法。如果允许代码的其他部分在迭代器中进行的调用之间调用这些方法,则会破坏列表的完整性,在这种情况下,同步变得毫无价值。
也许有些方法可以使用而不需要使用synchronizedCollection
包装列表的同步块(例如检查列表中有多少元素),但是如果使用列表和一个方法取决于另一个被调用方法的精确结果,在两个方法调用周围都需要一个synchronized块,以确保没有其他任何东西可以触及这些调用之间的列表状态。
答案 1 :(得分:3)
原因是迭代操作不能保持列表上的锁。例如,只要检查i.hasNext()
,hasNext()
就会锁定列表,但在您实际调用{{1}之前,列表可能会再次更改 }。
因此,您必须自己锁定列表,以使整个迭代保持同步,而不是单独执行每个操作。
答案 2 :(得分:0)
想象一下iterator
循环在两个不同的线程中运行。一个线程调用i.next().remove()
而另一个线程在同一个list
上循环是完全合法的,这可能会破坏列表中数据的一致性。