在JDK 1.6中的HashSet.java中,有一些关于HashSet迭代器的fail-fast属性的注释。
此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时间修改了集合,除了通过迭代器自己的remove方法之外,Iterator抛出ConcurrentModificationException。因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来不确定的时间冒着任意的,非确定性行为的风险。
我可以理解上面的段落,因为它非常简单明了,但我无法理解以下段落。如果我有一些简单的例子表明故障快速迭代器甚至可能失败,我可能会理解它。
请注意,迭代器的快速失败行为无法得到保证,因为一般来说,在存在非同步并发修改的情况下,不可能做出任何硬性保证。失败快速迭代器会尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的程序以确保其正确性是错误的:迭代器的快速失败行为应仅用于检测错误。
答案 0 :(得分:2)
EDIT2:这也更有可能发生在多线程环境中,你有两个线程,一个读取,一个写入。编码时很难看到这些。要修复那些你需要在列表上实现读/写锁定以避免这种情况的那些。
以下是评论的代码示例:
Iterator itr = myList.iterator();
while(itr.hasNext())
{
Object o = itr.next();
if(o meets some condition)
{
//YOURE MODIFYING THE LIST
myList.remove(o);
}
}
规范的含义是你不能依赖这样的代码:
while(itr.hasNext())
{
Object o = itr.next();
try
{
if(o meets some condition)
myList.remove(o);
}
catch(ConcurrentModificationException e)
{
//Whoops I abused my iterator. Do something else.
}
}
相反,您应该将内容添加到新列表中,然后将myList引用切换为刚刚创建的引用。这可以解释这种情况吗?
答案 1 :(得分:2)
第二段背后的想法是阻止你编写这样的代码:
boolean ok = false;
do {
try {
doTheModification();
ok = true;
} catch {
// Consurrent modification - retry
}
} while (!ok);
虽然这不是一个好的代码,但注释表明此代码无效(相反,例如,次优)。他们说异常可能根本不会发生,所以上述循环可能会无声地产生失败。