Java LinkedHashMap上的同步问题

Java LinkedHashMap上的同步问题,java,linkedhashmap,Java,Linkedhashmap,关于LinkedHashMap的同步特性,有一点让我感到困惑。这里是相关的Javadoc,我对此感到困惑。我的困惑点是,为什么remove方法在这里是特殊的,正如--“除了通过迭代器自己的remove方法之外” 该类的所有集合视图方法返回的集合的迭代器方法返回的迭代器是快速失效的:如果在迭代器创建后的任何时间,以迭代器自己的remove方法以外的任何方式修改映射,迭代器将抛出ConcurrentModificationException。因此,在面对并发修改时,迭代器会快速、干净地失败,而不是

关于LinkedHashMap的同步特性,有一点让我感到困惑。这里是相关的Javadoc,我对此感到困惑。我的困惑点是,为什么remove方法在这里是特殊的,正如--“除了通过迭代器自己的remove方法之外”

该类的所有集合视图方法返回的集合的迭代器方法返回的迭代器是快速失效的:如果在迭代器创建后的任何时间,以迭代器自己的remove方法以外的任何方式修改映射,迭代器将抛出ConcurrentModificationException。因此,在面对并发修改时,迭代器会快速、干净地失败,而不是在将来的不确定时间冒着任意、不确定行为的风险

提前感谢,,
Lin

基本上,不允许在对映射进行迭代时从结构上修改映射,因为这样做会使迭代器无效

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

Iterator<E> it = coll.iterator();
while (it.hasNext()) {
  E val = it.next();
  if (some_condition) {
    it.remove();
  }
}
Iterator it=coll.Iterator();
while(it.hasNext()){
E val=it.next();
如果(某些条件){
it.remove();
}
}

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


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

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

这是因为,如前所述:

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


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

谢谢NPE,很抱歉回复太晚。既然Iterator.remove只是从迭代器本身删除一个元素,它不会影响原始映射本身,所以它是安全的?谢谢Sanjay,很抱歉回复太晚。既然Iterator.remove只是从迭代器本身删除一个元素,它不会影响原始映射本身,所以它是安全的?@LinMa:No;迭代器可以看作是一个集合无关的对象,用于迭代项并更改它们。迭代器本身没有任何数据;这只是对原始数据的读/写视图。谢谢Sanjay,为什么Iterator.remove()不受我提到的Javadoc的限制?@LinMa:那是因为
LinkedHashMap
和其他
Map
类没有迭代器方法。这里的Javadoc讨论的是在执行类似于
yourMap.entrySet().iterator()的操作时返回的迭代器。仔细阅读“该类的所有集合视图方法返回的集合的迭代器方法”这句话。它说的是这个类的视图方法,而不是这个类的迭代器方法。@Lin Ma:正如前面提到的,我们的想法是控制集合的变异。假设您在集合上进行交互,突然一些元素在不使用迭代器的情况下被删除。Fail fast iterator保证在发生异常时通过异常通知您。现在,假设我们希望使用迭代器进行迭代,同时使用相同的迭代器删除元素。我们该怎么做呢?这就是
remove
方法发挥作用的地方。如果您查看任何集合类的代码,您应该能够看到执行此操作的逻辑。谢谢Jack,很抱歉回复太晚。既然Iterator.remove只是从迭代器本身删除一个元素,它不会影响原始映射本身,那么它是安全的吗?