无法理解这篇关于失败快速的评论

时间:2012-08-27 16:05:37

标签: java iterator hashset fail-fast

在JDK 1.6中的HashSet.java中,有一些关于HashSet迭代器的fail-fast属性的注释。

  

此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时间修改了集合,除了通过迭代器自己的remove方法之外,Iterator抛出ConcurrentModificationException。因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来不确定的时间冒着任意的,非确定性行为的风险。

我可以理解上面的段落,因为它非常简单明了,但我无法理解以下段落。如果我有一些简单的例子表明故障快速迭代器甚至可能失败,我可能会理解它。

  

请注意,迭代器的快速失败行为无法得到保证,因为一般来说,在存在非同步并发修改的情况下,不可能做出任何硬性保证。失败快速迭代器会尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的程序以确保其正确性是错误的:迭代器的快速失败行为应仅用于检测错误。

2 个答案:

答案 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);

虽然这不是一个好的代码,但注释表明此代码无效(相反,例如,次优)。他们说异常可能根本不会发生,所以上述循环可能会无声地产生失败。