为什么在交互中同步集合中再次同步?

时间:2013-02-16 22:09:02

标签: java multithreading synchronized

在Java文档中,它说必须在迭代中再次手动同步同步集合。这是为什么?由于返回的集合已经同步。不太明白为什么会这样。谢谢。

 Collection c = Collections.synchronizedCollection(myCollection);
      ...
    synchronized(c) {
        Iterator i = c.iterator(); // Must be in the synchronized block
        while (i.hasNext())
          foo(i.next());
   }

3 个答案:

答案 0 :(得分:3)

仅同步各个方法。如果允许代码的其他部分在迭代器中进行的调用之间调用这些方法,则会破坏列表的完整性,在这种情况下,同步变得毫无价值。

也许有些方法可以使用而不需要使用synchronizedCollection包装列表的同步块(例如检查列表中有多少元素),但是如果使用列表和一个方法取决于另一个被调用方法的精确结果,在两个方法调用周围都需要一个synchronized块,以确保没有其他任何东西可以触及这些调用之间的列表状态。

答案 1 :(得分:3)

原因是迭代操作不能保持列表上的锁。例如,只要检查i.hasNext()hasNext()就会锁定列表,但在您实际调用{{1}之前,列表可能会再次更改 }。

因此,您必须自己锁定列表,以使整个迭代保持同步,而不是单独执行每个操作。

答案 2 :(得分:0)

想象一下iterator循环在两个不同的线程中运行。一个线程调用i.next().remove()而另一个线程在同一个list上循环是完全合法的,这可能会破坏列表中数据的一致性。