Fail-fast机制

Fail-fast机制

“Fail Fast”机制――列表的结构在其返回遍历器(Iterator)后的任何时候发生变化(这种变化不包括遍历器本身调用remove方法移除元素)后,将会导致遍历器抛出异常的机

制。
JDK中所谓的FailFast机制,就是在错误发生后,其它对象立即会有所反应。不会留待以后处理,或者忽略不计。可以参阅2004年《IEEE Software》中Martin Fowler所写的《Fail

Faster》。

失败机制
Failing slowly
Failing fast

Most languages have built-in assertions,but they don’t always throw exceptions.They’re also usually pretty generic, limiting
expressiveness and causing duplication.
For these reasons, I usually prefer to implement my own assertion class.

断言是快速失败机制的主要构成部分。
Assertions are the key to failing fast. An assertion is a tiny piece of code that checks a condition
and then fails if the condition isn’t met. So, when something starts to go wrong, an assertion
detects the problem and makes it visible.

不要试图关闭断言。
One reaction to this fear is to disable assertions in the field. Don’t do that!
Remember, an error that occurs at the customer’s site made it through your testing process. You’ll probably have trouble reproducing
it. These errors are the hardest to find, and a well-placed assertion explaining the problem could save you days of effort.

快速失败是一种机制。
Fail-fast is a property of a system or module with respect to its response to failures. A fail-fast system is designed to immediately report at its interface

any failure or condition that is likely to lead to failure. Fail-fast systems are usually designed to stop normal operation rather than attempt to continue a

possibly-flawed process. Such designs often check the system’s state at several points in an operation, so any failures can be detected early. A fail-fast

module passes the responsibility for handling errors, but not detecting them, to the next-higher system design level.

Fail-fast systems or modules are desirable in several circumstances:
When building a fault-tolerant system by means of redundant components, the individual components should be fail-fast to give the system enough information

to successfully tolerate a failure.
Fail-fast components are often used in situations where failure in one component might not be visible until it leads to failure in another component.
Finding the cause of a failure is easier in a fail-fast system, because the system reports the failure with as much information as possible as close to the

time of failure as possible. In a fault-tolerant system, the failure might go undetected, whereas in a system that is neither fault-tolerant nor fail-fast

the failure might be temporarily hidden until it causes some seemingly-unrelated problem later.
A fail-fast system that is designed to halt as well as report the error on failure is less likely to erroneously perform an irreversible or costly operation.

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。
Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的

对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同

时维护索引的一致性。

有意思的是如果你的 Collection / Map 对象实际只有一个元素的时候, ConcurrentModificationException 异常并不会被抛出。也就是在 javadoc 里面指出: it would be

wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

附:来自ibm developerworks上对java.util.concurrent包的说明片段:
java.util 包中的集合类都返回 fail-fast 迭代器,这意味着它们假设线程在集合内容中进行迭代时,集合不会更改它的内容。如果 fail-fast 迭代器检测到在迭代过程中进

行了更改操作,那么它会抛出 ConcurrentModificationException ,这是不可控异常。
在迭代过程中不更改集合的要求通常会对许多并发应用程序造成不便。相反,比较好的是它允许并发修改并确保迭代器只要进行合理操作,就可以提供集合的一致视图,如

java.util.concurrent 集合类中的迭代器所做的那样。
java.util.concurrent 集合返回的迭代器称为弱一致的(weakly consistent)迭代器。对于这些类,如果元素自从迭代开始已经删除,且尚未由 next() 方法返回,那么它将

不返回到调用者。如果元素自迭代开始已经添加,那么它可能返回调用者,也可能不返回。在一次迭代中,无论如何更改底层集合,元素不会被返回两次。

References

http://en.wikipedia.org/wiki/Fail-fast

http://martinfowler.com/ieeeSoftware/failFast.pdf

Collection中的FailFast

http://blog.csdn.net/lianyu2008/archive/2009/10/10/4651451.aspx

http://my.unix-center.net/~Zianed/?p=1142


发布了111 篇原创文章 · 获赞 11 · 访问量 66万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章