为什么此代码不引发ConcurrentModificationException?

时间:2019-09-12 20:34:49

标签: java

我试图理解为什么我的某些代码没有引发ConcurrentModificationException。我正在遍历Set的元素,然后将更多元素添加到Set中,但是我期望出现异常。

问题:给定一个有向树,如果两个给定的节点有一个共同祖先,则返回true。请注意,这不是一棵有根的树(即一棵有根的树)。给我们的是(父,子)边对。节点具有唯一的ID。

async function update() {
     const t1 = new Date();
     await wait_for_response();
     setTimeout(update, Math.max(0, 1000 - new Date + t1));
}
update();

1 个答案:

答案 0 :(得分:0)

在某些输入下,此代码可能仍会引发ConcurrentModificationException。从Javadoc中获取例外:

  

请注意,不能保证快速故障行为,因为通常来说,在存在不同步的并发修改的情况下,不可能做出任何严格的保证。快速失败操作会尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的程序的正确性是错误的:ConcurrentModificationException应该仅用于检测错误。

作为示例,此代码可以正常工作:

public final class Main {

    public static void main(String[] args) {
        Set<Integer> numbers = new HashSet<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);

        for (Integer n : numbers) {
            numbers.add(n + 1);
        }

        System.out.println(numbers); // [1, 2, 3, 4]
    }
}

但这会抛出ConcurrentModificationException

public final class Main {

    public static void main(String[] args) {
        Set<Integer> numbers = new HashSet<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);

        for (Integer n : numbers) {
            // Changed 1 to a 10.
            numbers.add(n + 10);
        }

        System.out.println(numbers);
    }
}

换句话说,代码的某些路径可能会导致ConcurrentModificationException,但其他路径可能不会,因此您不应该依赖此结果。