为什么迭代器被称为故障安全或快速失败?

时间:2015-10-26 17:30:25

标签: java collections iterator concurrentmodification

为什么迭代器被称为“故障安全”和“快速失败”,即使Iterator.remove()在迭代ConcurrentModificationException时没有抛出任何Collection(例如,{{} 1}})使用HashMap

3 个答案:

答案 0 :(得分:1)

顾名思义,一旦他们意识到自迭代开始以来收集的结构已经改变,那么失败快速迭代器就会失败。结构更改意味着在一个线程迭代该集合时添加,删除或更新集合中的任何元素。通过保持修改计数来实现失败快速行为,如果迭代线程实现修改计数的更改,则会抛出ConcurrentModificationException。

与故障快速迭代器相反,如果在结构上修改了Collection,则故障安全迭代器不会抛出任何异常 虽然有一个线程迭代它,因为它们可以克隆Collection而不是原始集合,这就是为什么它们被称为故障安全迭代器。 CopyOnWriteArrayList的迭代器是一个故障安全Iterator的示例,也是由ConcurrentHashMap编写的迭代器,keySet也是故障安全迭代器,永远不会在Java中抛出ConcurrentModificationException。

答案 1 :(得分:0)

使用Iterator.remove()不会抛出ConcurrentModificationException,但如果其他内容(在另一个帖子中)修改了支持Collection的{​​{1}}在迭代期间,它会。

来自Iterator的Java API文档;我大胆地强调:

  

此类的iterator和listIterator方法返回的迭代器是 fail-fast :如果在创建迭代器后的任何时候对列表进行结构修改,除了通过迭代器自己的remove或add方法,迭代器将抛出一个java.util.ArrayList

然后,同一文档的下一句话将解释在这种情况下快速失败的确切含义;再次,我大胆地强调:

  

因此,面对并发修改,迭代器会快速而干净地失败,而不是冒着将来未确定时间的任意非确定性行为的风险。

换句话说,如果另一个线程修改了集合,那么简单而安全的事情就是以ConcurrentModificationException的形式导致故意的,明确的失败,而不是试图找出一个非失败的,即故障安全,逻辑(例如通过ConcurrentModificationException显示修改,具体取决于该元素是否已被迭代),这可能是复杂且容易出错的。 / p>

答案 2 :(得分:0)

  • 故障安全迭代器意味着即使集合为,它们也不会引发任何异常 在迭代时进行修改。
  • 而如果以下情况发生,那么快速失败迭代器将引发异常(ConcurrentModificationException): 集合在迭代时被修改。