他们之间有什么区别...
“故障安全”(在工程方面 https://en.wikipedia.org/wiki/Fail-safe) 表示某事物发生故障但不会造成损害或造成损害极小。严格来说,有没有这样的事在 Java 中作为故障安全迭代器。如果迭代器失败(通常意义上的“失败”),则可能会发生损坏。
我怀疑你实际上是指“弱一致”迭代器。 javadoc 说:
“大多数并发 Collection 实现(包括大多数队列)也与通常的 java.util 约定不同,因为它们的 Iterators 和 Spliterators 提供弱一致性而不是快速失败遍历。”
通常,弱一致性意味着如果集合与迭代同时修改,则迭代所见内容的保证会更弱。 (详细信息将在每个并发集合类 javadocs 中指定。)
"Fail-fast" (in systems design https://en.wikipedia.org/wiki/Fail-fast) means that the failure condition is checked aggressively so that the failure condition is (where possible1) detected before too much damage can be done. In Java, a fail-fast iterator fails by throwing a ConcurrentModificationException
.
“快速失败”和“弱一致性”的替代方案是迭代可能不可预测地失败的语义;例如有时会给出错误的答案或抛出意外的异常。 (这是某些标准实现的行为Enumeration
Java 早期版本中的 API。)
...它们与我们用于收集的迭代器不同吗?
No. These are properties of the iterators implemented by standard Collection types; i.e. they are either "fail fast" or "weakly consistent" ... when used correctly with respect to synchronization and the Java memory model1.
快速失败迭代器是通常使用一个实现volatile
集合对象上的计数器。
- 当集合更新时,计数器会递增。
- When an
Iterator
创建后,计数器的当前值嵌入到Iterator
object.
- When an
Iterator
执行操作后,该方法会比较两个计数器值,如果不同则抛出 CME。
相比之下,弱一致性迭代器通常是轻量级的,并且利用每个并发集合的内部数据结构的属性。没有一般模式。如果您有兴趣,请阅读不同集合类的源代码。
1 - The rider is that fail-fast iterator behavior assumes that the application is correctly implemented with respect to synchronization and the memory model. (In other words, the application is thread-safe.) For example, if you iterated an ArrayList
without proper synchronization, the "fast fail" mechanism should detect the concurrent modification (though that isn't guaranteed), but may not prevent the list from being corrupted due to the application's unsafe behavior. To illustrate, the javadoc http://docs.oracle.com/javase/8/docs/api/java/util/Vector.html#fail-fast for Vector.iterator()
says this:
"The fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException
on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs."