105

Java 中有两种类型的迭代器:故障安全和快速故障。

这是什么意思,它们之间的区别是什么?

4

4 回答 4

88

它们之间有什么区别...

“故障安全”(在工程中)是指某事以一种不会造成损害或造成损害最小的方式发生故障。严格来说, Java 中存在故障安全迭代器。如果迭代器失败(在正常意义上的“失败”),您可以预期会发生损坏。

我怀疑您实际上是指“弱一致”迭代器。javadoc 说:

“大多数并发 Collection 实现(包括大多数队列)也不同于通常的 java.util 约定,因为它们的 Iterators 和 Spliterators 提供弱一致而不是快速失败遍历。”

通常,弱一致性意味着如果一个集合与迭代同时被修改,那么对迭代所看到的内容的保证会更弱。(详细信息将在每个并发集合类 javadocs 中指定。)

“Fail-fast”(在系统设计中)意味着积极检查故障条件,以便在造成过多损坏之前(在可能的情况下1 )检测到故障条件。在 Java 中,快速失败的迭代器通过抛出ConcurrentModificationException.

“快速失败”和“弱一致”的替代方案是迭代失败不可预测的语义;例如,有时给出错误的答案或抛出意外的异常。Enumeration(这是Java 早期版本中 API的一些标准实现的行为。)

...它们与我们用于收集的迭代器不同吗?

不,这些是标准 Collection 类型实现的迭代器的属性;即,它们要么是“快速失败”,要么是“弱一致”……当正确使用同步和Java 内存模型1时。


快速失败的迭代器通常使用volatile集合对象上的计数器来实现。

  • 当集合更新时,计数器会增加。
  • 创建anIterator时,计数器的当前值嵌入到Iterator对象中。
  • 执行操作时Iterator,该方法比较两个计数器值,如果它们不同,则抛出 CME。

相比之下,弱一致性迭代器通常是轻量级的,并利用每个并发集合的内部数据结构的属性。没有通用模式。如果您有兴趣,请阅读不同集合类的源代码。


1 - 快速失败迭代器行为假设应用程序在同步和内存模型方面正确实现。(换句话说,应用程序是线程安全的。)例如,如果您在ArrayList没有适当同步的情况下迭代一个,“快速失败”机制应该检测到并发修改(尽管不能保证),但可能不会阻止列表由于应用程序的不安全行为而损坏。为了说明,javadoc forVector.iterator()是这样说的:

“无法保证迭代器的快速失败行为,因为一般来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。快速失败迭代器ConcurrentModificationException在尽力而为的基础上抛出。因此,它将是编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测错误。”

于 2013-06-29T07:09:34.500 回答
42

它们是相当快速失败弱一致性的类型:

如果集合在迭代时被集合的方法(添加/删除)修改,则java.util包中的迭代器会抛出ConcurrentModificationException

包中的迭代器java.util.concurrent通常迭代快照并允许并发修改,但在创建迭代器后可能不会反映集合更新。

于 2013-06-29T06:45:03.053 回答
21

唯一的区别是故障安全迭代器不会抛出任何异常,这与故障快速迭代器相反。

如果 Collection 在结构上被修改,而一个线程正在对其进行迭代。这是因为它们在 Collection 的克隆而不是原始集合上工作,这就是为什么它们被称为故障安全迭代器。

CopyOnWriteArrayList 的迭代器是故障安全迭代器的一个示例,也是由 ConcurrentHashMap 编写的迭代器 keySet 也是故障安全迭代器,在 Java 中从不抛出 ConcurrentModificationException。

于 2013-06-29T06:31:12.707 回答
1

这种情况与“并发处理”有关,意味着不止一个用户访问同一资源。在这种情况下,其中一个用户尝试修改导致“ConcurrentProcessingException”的资源,因为在这种情况下,其他用户会获得不正确的数据。这两种类型都与这种情况有关。

简单来说,

快速失败:

  • 如果发生结构修改(添加、更新、删除),迭代器会立即抛出 ConcurrentModificationException。
  • 示例:ArrayList、HashMap、TreeSet

故障安全:

  • 这里迭代器不会抛出任何异常,因为它们在集合的克隆上操作,而不是原始集合。因此,它们是故障安全迭代器。
  • 示例:CopyOnWriteArrayList、ConcurrentHashMap
于 2020-05-06T17:48:16.307 回答