LinkedHashMap上的同步问题

时间:2013-02-03 13:53:15

标签: java linkedhashmap

我对关于LinkedHashMap的同步特性的一个特定点感到困惑。以下是我感到困惑的相关Javadoc。我的困惑之处在于,为什么删除方法在这里是特殊的,这是由“ - 通过迭代器自己的删除方法除外”提到的?

http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html

由所有类的集合视图方法返回的集合的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的迭代器之外remove方法,迭代器将抛出一个ConcurrentModificationException。因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来不确定的时间冒着任意的,非确定性行为的风险。

提前谢谢, 林

3 个答案:

答案 0 :(得分:5)

基本上,你不允许在迭代时对结构进行结构修改,因为这样做会使迭代器失效。

Iterator.remove()特别免除此功能,使您能够轻松编写如下代码:

Iterator<E> it = coll.iterator();
while (it.hasNext()) {
  E val = it.next();
  if (some_condition) {
    it.remove();
  }
}

答案 1 :(得分:2)

这不是特别的,它是使用迭代器时从集合中删除某些项目的常规方法。如果在迭代器“外部”移除元素,则与实际集合相比,给定集合的迭代器视图变得不一致,因为迭代器无法知道元素被移除的原因或方式。

迭代器可以是不同类型的。有一些迭代器在集合的给定状态下“操作”,在这种情况下修改迭代器外部的集合没有任何区别。这对于不可变集合很常见。另一种类型的迭代器是一个“快速失败”的迭代器,它会在发现迭代器现在正在查看集合的旧状态(即集合是从外部修改)时抛出异常。正如文档中所提到的,LinkedHashMap使用了一个快速失败的迭代器。

答案 2 :(得分:1)

它并不特别,它会在LinkedHashMap上获得一种锁定,这样您就可以通过remove方法删除元素。

这是因为,如前所述:

  

结构修改是添加或删除一个或多个映射的任何操作,或者在访问顺序链接的哈希映射的情况下,会影响迭代顺序。

这意味着您在数据结构上有一个挂起的迭代器,允许任何修改都会产生与确定性行为有关的问题(因为迭代器会变得不一致,因为底层结构发生了变化)。因此,如果您在其上有一个打开的迭代器,则只要调用任何方法,实现就会使任何结构修改失败并出现异常。