2

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

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

3 回答 3

3

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

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

于 2013-02-16T22:11:50.690 回答
3

原因是迭代操作无法保持链表上的锁。例如,i.hasNext()将锁定列表,只要它需要检查hasNext(),但列表可能会在您实际调用之前再次next()更改。

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

于 2013-02-16T22:11:55.657 回答
0

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

于 2013-02-16T22:17:43.500 回答