Java中的故障安全和故障快速迭代器是什么

2022-08-31 09:57:20

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

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


答案 1

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

“故障安全”(在工程中)意味着某些东西以不造成或最小损害的方式发生故障。严格来说,Java中没有故障安全迭代器这样的东西。如果迭代器失败(在正常意义上的“失败”),您可以预期会发生损坏。

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

“大多数并发集合实现(包括大多数队列)也与通常的java.util约定不同,因为它们的迭代器和拆分器提供弱一致性而不是快速失败遍历。

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

“快速故障”(在系统设计中)意味着对故障条件进行严格检查,以便在造成太大损害之前(在可能的情况下1)检测到故障条件。在 Java 中,快速失败迭代器通过抛出 .ConcurrentModificationException

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

...它们是否与我们用于收集的迭代器不同。

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


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

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

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


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

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


答案 2

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

如果在迭代时集合的方法修改了集合(添加/删除),则从包抛出迭代器java.utilConcurrentModificationException

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