简体   繁体   English

为什么这段代码不抛出 ConcurrentModificationException?

[英]Why does this code NOT throw a ConcurrentModificationException?

I'm trying to understand why some of my code doesn't throw a ConcurrentModificationException.我试图理解为什么我的一些代码不会抛出 ConcurrentModificationException。 I am looping through elements of a Set and then adding more elements to the set, but I expected an exception.我循环遍历 Set 的元素,然后向该集合添加更多元素,但我预计会出现异常。

Problem: Given a directed tree, return true if two given nodes have a common ancestor.问题:给定一棵有向树,如果两个给定的节点有一个共同的祖先,则返回 true。 Note this is not a rooted tree (ie a tree with one root).请注意,这不是一棵有根的树(即只有一个根的树)。 We are given edge pairs that are (parent, child).我们得到的边对是(父母,孩子)。 Nodes have unique IDs.节点具有唯一的 ID。

import java.io.*;
import java.util.*;


class Solution {
  public static void main(String[] args) {
    int[][] pairs = {{11,6},{9,6},{9,8},{10,8}, {6,2},{5,2},{5,1},{8,3},{8,4}};

    System.out.println(hasCommonAncestor(pairs, 3,4));
    System.out.println(hasCommonAncestor(pairs, 2,4));    
    System.out.println(hasCommonAncestor(pairs, 1,3));
    System.out.println(hasCommonAncestor(pairs, 6,8));    

  }


  private static boolean hasCommonAncestor(int[][] pairs, int a, int b) {
    Map<Integer, Set<Integer>> firstLevelParents = new HashMap<>();

    for(int[] pair : pairs) {
      int parent = pair[0];
      int child = pair[1];
      Set<Integer> parents = firstLevelParents.getOrDefault(child, new HashSet<>());
      parents.add(parent);
      firstLevelParents.put(child, parents);
    }


    Set<Integer> aParents = firstLevelParents.get(a);
    Set<Integer> bParents = firstLevelParents.get(b);

    for(Integer parent : aParents) {
      Set<Integer> parentsParents = firstLevelParents.getOrDefault(parent, new HashSet<>());
      aParents.addAll(parentsParents);
    }

    for(Integer parent : bParents) {
      Set<Integer> parentsParents = firstLevelParents.getOrDefault(parent, new HashSet<>());
      bParents.addAll(parentsParents);
    }


    return aParents.removeAll(bParents);
  }
}

This code may still throw a ConcurrentModificationException under certain inputs.此代码可能仍会在某些输入下引发ConcurrentModificationException From the Javadoc for the exception:来自 Javadoc 的异常:

Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification.请注意,不能保证快速失败行为,因为一般来说,在存在非同步并发修改的情况下不可能做出任何硬保证。 Fail-fast operations throw ConcurrentModificationException on a best-effort basis.快速失败操作会尽最大努力抛出 ConcurrentModificationException。 Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.因此,编写一个依赖此异常来确保其正确性的程序是错误的: ConcurrentModificationException 应该仅用于检测错误。

As an example, this code works fine:例如,此代码工作正常:

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]
    }
}

But this will throw a 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) {
            // Changed 1 to a 10.
            numbers.add(n + 10);
        }

        System.out.println(numbers);
    }
}

In other words, some paths of your code may lead to a ConcurrentModificationException but others may not and you should not depend on this result.换句话说,您的代码的某些路径可能会导致ConcurrentModificationException但其他路径可能不会,您不应该依赖此结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么这段代码会引发ConcurrentModificationException? - Why does this code throw ConcurrentModificationException? 为什么这段代码会抛出 java ConcurrentModificationException? - Why does this code throw a java ConcurrentModificationException? 为什么这段代码不抛出 ConcurrentModificationException? - Why doesn't this code throw a ConcurrentModificationException? 为什么 iterator.remove 不抛出 ConcurrentModificationException - Why iterator.remove does not throw ConcurrentModificationException 为什么这段代码不会触发 ConcurrentModificationException? - Why this code does not trigger ConcurrentModificationException? 为什么 ArrayList 从多线程修改时不抛出 ConcurrentModificationException? - Why does ArrayList not throw ConcurrentModificationException when modified from multiple threads? 为什么it.next()抛出java.util.ConcurrentModificationException? - Why does it.next() throw java.util.ConcurrentModificationException? 为什么一个循环抛出一个ConcurrentModificationException,而另一个不抛出? - Why does one loop throw a ConcurrentModificationException, while the other doesn't? 为什么我的applet的paint方法抛出ConcurrentModificationException - Why does my applet's paint method throw a ConcurrentModificationException 为什么这段代码会在Java中导致ConcurrentModificationException? - Why does this code cause a ConcurrentModificationException in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM