简体   繁体   English

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

[英]What are fail-safe & fail-fast Iterators in Java

There are two types of iterators in Java: fail-safe and fail-fast. Java 中有两种类型的迭代器:fail-safe 和 fail-fast。

What does this mean, and is the difference between them?这是什么意思,它们之间有什么区别?

What is the difference between them ...它们之间有什么区别...

"Fail-safe" ( in engineering ) means that something fails in a way that causes no or minimal damage. “故障安全”(在工程中)意味着某些故障不会造成损坏或造成最小损坏。 Strictly speaking, there is no such thing in Java as a fail-safe iterator.严格来说,Java 中没有故障安全迭代器这样的东西 If an iterator fails (in the normal sense of "fail"), you can expect damage to occur.如果迭代器失败(在正常意义上的“失败”),您可以预期会发生损坏。

I suspect that you actually mean "weakly consistent" iterators.我怀疑您实际上是指“弱一致性”迭代器。 The javadoc says: javadoc 说:

"Most concurrent Collection implementations (including most Queues) also differ from the usual java.util conventions in that their Iterators and Spliterators provide weakly consistent rather than fast-fail traversal." “大多数并发集合实现(包括大多数队列)也不同于通常的 java.util 约定,因为它们的迭代器和拆分器提供弱一致性而不是快速失败遍历。”

Typically, weak consistency means that if a collection is modified concurrently with an iteration, the guarantees of what the iteration sees are weaker.通常,弱一致性意味着如果集合在迭代的同时被修改,则迭代所看到的内容的保证较弱。 (The details will be specified in each concurrent collection classes javadocs.) (详细信息将在每个并发集合类 javadocs 中指定。)

"Fail-fast" ( in systems design ) means that the failure condition is checked aggressively so that the failure condition is (where possible 1 ) detected before too much damage can be done. “Fail-fast”(在系统设计中)意味着积极检查故障情况,以便在造成过多损坏之前检测到故障情况(如果可能1 )。 In Java, a fail-fast iterator fails by throwing a ConcurrentModificationException .在 Java 中,快速失败的迭代器通过抛出ConcurrentModificationException失败。

The alternative to "fail-fast" and "weakly consistent" is semantic where the iteration fails unpredictably; “快速失败”和“弱一致性”的替代方案是语义,其中迭代失败不可预测; eg to sometimes give the wrong answer or throw an unexpected exception.例如,有时会给出错误的答案或抛出意外的异常。 (This was the behavior of some standard implementations of the Enumeration API in early versions of Java.) (这是 Java 早期版本中Enumeration API 的一些标准实现的行为。)

... and are they different from the iterator we use for collection. ...它们与我们用于收集的迭代器不同吗?

No. These are properties of the iterators implemented by standard Collection types;不。这些是由标准集合类型实现的迭代器的属性 ie they are either "fail fast" or "weakly consistent" ... when used correctly with respect to synchronization and the Java memory model 1 .即它们要么是“快速失败”,要么是“弱一致性”......当正确使用同步和 Java 内存模型1 时


Fail-fast iterators are typically implemented using a volatile counter on the collection object.快速失败迭代器通常使用集合对象上的volatile计数器实现。

  • When the collection is updated, the counter is incremented.当集合更新时,计数器增加。
  • When an Iterator is created, the current value of the counter is embedded in the Iterator object.创建Iterator ,计数器的当前值嵌入在Iterator对象中。
  • When an Iterator operation is performed, the method compares the two counter values and throws a CME if they are different.当执行Iterator操作时,该方法比较两个计数器值,如果它们不同,则抛出 CME。

By contrast, weakly consistent iterators are typically light-weight and leverage properties of each concurrent collection's internal data structures.相比之下,弱一致性迭代器通常是轻量级的,并且利用了每个并发集合的内部数据结构的特性。 There is no general pattern.没有通用的模式。 If you are interested, read the source code for different collection classes.如果您有兴趣,请阅读不同集合类的源代码。


1 - The rider is that fail-fast behavior assumes that the application id correctly with respect to synchronization and the memory model. 1 - 骑手是快速失败行为假设应用程序 id 在同步和内存模型方面是正确的。 That means that (for example) if you iterate an ArrayList without proper synchronization, the result could be a corrupted list result.这意味着(例如)如果在没有适当同步的情况下迭代ArrayList ,结果可能是损坏的列表结果。 The "fast fail" mechanism will probably detect the concurrent modification (though that isn't guaranteed), but it won't detect the underlying corruption. “快速失败”机制可能会检测到并发修改(尽管不能保证),但它不会检测到潜在的损坏。 As an example, javadoc for Vector.iterator() says this:例如, Vector.iterator() javadocVector.iterator()说的:

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

They are rather fail-fast and weakly-consistent types:它们是相当快速弱一致的类型:

Iterators from java.util package throw ConcurrentModificationException if collection was modified by collection's methods (add / remove) while iterating如果在迭代时集合的方法(添加/删除)修改了集合,则java.util包中的迭代器会抛出ConcurrentModificationException

Iterators from java.util.concurrent package typically iterate over a snapshot and allow concurrent modifications but may not reflect collection updates after the iterator was created. java.util.concurrent包中的迭代器通常迭代快照并允许并发修改,但在创建迭代器后可能不会反映集合更新。

The only difference is fail-safe iterator doesn't throw any Exception, contrary to fail-fast Iterator.唯一的区别是故障安全迭代器不会抛出任何异常,这与故障快速迭代器相反。

If Collection is modified structurally while one thread is iterating over it.如果在一个线程迭代它时在结构上修改了 Collection。 This is because they work on clone of Collection instead of original collection and that's why they are called as fail-safe iterator.这是因为它们处理的是 Collection 的克隆而不是原始集合,这就是它们被称为故障安全迭代器的原因。

Iterator of CopyOnWriteArrayList is an example of fail-safe Iterator also iterator written by ConcurrentHashMap keySet is also fail-safe iterator and never throw ConcurrentModificationException in Java. CopyOnWriteArrayList 的迭代器是故障安全迭代器的一个例子,由 ConcurrentHashMap keySet 编写的迭代器也是故障安全迭代器,在 Java 中从不抛出 ConcurrentModificationException。

This scenario relate with "concurrent processing", means that more then one user accessing the same resource.此场景与“并发处理”相关,意味着有多个用户访问同一资源。 In such situation, one of the user try to modify that resource which cause the 'ConcurrentProcessingException' because in that case other user get improper data.在这种情况下,其中一个用户尝试修改导致“ConcurrentProcessingException”的资源,因为在这种情况下其他用户获得了不正确的数据。 Both this type relate with this kind of situation.这两种类型都与这种情况有关。

In simple term,简单来说,

Fail-Fast :快速失败:

  • Iterators immediately throw ConcurrentModificationException if structural modification(add, update, delete) happens.如果发生结构修改(添加、更新、删除),迭代器会立即抛出 ConcurrentModificationException。
  • Example : ArrayList, HashMap, TreeSet示例:ArrayList、HashMap、TreeSet

Fail-Safe :故障安全:

  • Here Iterators not throw any exception because they operate on the clone of the collection, not original one.这里迭代器不会抛出任何异常,因为它们操作的是集合的克隆,而不是原始集合。 So, that they are fail-safe iterators.因此,它们是故障安全迭代器。
  • Example : CopyOnWriteArrayList, ConcurrentHashMap示例:CopyOnWriteArrayList、ConcurrentHashMap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM