无法理解此关于fail-fast的评论



在JDK1.6中的HashSet.java中,有一些关于HashSet迭代器的fail-fast属性的评论。

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

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

请注意,迭代器的故障快速行为无法得到保证,因为一般来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。故障快速迭代器在尽力而为的基础上抛出ConcurrentModificationException。因此,编写一个依赖于此异常的正确性的程序是错误的:迭代器的快速故障行为应该只用于检测错误。

EDIT:很抱歉我使用了一个列表,但这是相同的想法。这是关于迭代器的,而不是它背后的Collection

编辑2:同样,这种情况在多线程环境中发生的可能性要大得多,在这种环境中,你有两个线程,一个读取,一个写入。当您进行编码时,很难看到这些。要解决这些问题,您需要在列表上实现读/写锁以避免这种情况。

以下是注释的代码示例:

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引用切换到刚刚创建的引用。这能解释情况吗?

第二段背后的想法是防止您编写这样的代码:

boolean ok = false;
do {
    try {
        doTheModification();
        ok = true;
    } catch {
        // Consurrent modification - retry
    }
} while (!ok);

虽然这不是一个好的代码,但注释指出该代码是无效的(与次优相反)。他们说,异常可能根本不会发生,所以上面的循环可能会无声地产生故障。

相关内容

  • 没有找到相关文章

最新更新