简体   繁体   English

迭代 ImmutableMap.copyof() 时出现 ConcurrentModificationException

[英]ConcurrentModificationException when iterate through ImmutableMap.copyof()

Currently, I have a problem when I frequently iterating through a HashMap (1-time per second)目前,我在频繁迭代 HashMap 时遇到问题(每秒 1 次)

I add new element to the map on the main thread and iterate the map on the other thread我在主线程上向地图添加新元素在另一个线程上迭代地图

I return an ImmutableMap.copyOf() to iterate through it, and sometimes I add a new element to the map.我返回一个 ImmutableMap.copyOf() 来遍历它,有时我会向地图添加一个新元素。 But it throws me a ConcurrentModificationException但它给我一个 ConcurrentModificationException

java.util.ConcurrentModificationException: null
  at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911) ~[?:1.8.0_261]
    at java.util.ArrayList$Itr.next(ArrayList.java:861) ~[?:1.8.0_261]

My pseudo-code:我的伪代码:

class Foo {
    private final Map<String, List<User>> userMap = new HashMap<>();

    public static void addUser(String houseId, User user) {
        if(!userMap.containsKey(houseId)) {
            userMap.put(houseId, new ArrayList<>());
        }
        List<User> list = userMap.get(houseId);
        list.add(user);
    }

    public static Map<String, List<User>> getAll() {
        return ImmutableMap.copyOf(userMap);
    }
}

// iterating task
// this task run one per second

class Task extends TimerTask {
    public void run() {
        for (List<User> listUser : Foo.getAll().values()) {
            for (User user : listUser) {
                user.sayHello(); // print hello
            }
        }
    }
}

I thought that use an ImmutableMap.copyOf() will prevent me from this problem.我认为使用 ImmutableMap.copyOf() 会阻止我解决这个问题。 Because I read that you should use an immutable copy of your list/map when iterating through it from other thread.因为我读到您应该在从其他线程迭代时使用列表/地图的不可变副本。

I think I "solve" this by using CopyOnWriteArrayList.我想我通过使用 CopyOnWriteArrayList 来“解决”这个问题。 But I'm really curious why it throws me an error.但我真的很好奇为什么它会给我一个错误。

Thank you!!!谢谢!!!

As you can see in the stack trace, the error occurs in the ArrayList, not the Map.正如您在堆栈跟踪中看到的,错误发生在 ArrayList 中,而不是 Map 中。 In method addUser , an element is added to the list via list.add(user);addUser方法中,一个元素通过list.add(user);添加到列表中list.add(user);

This operation might happen, while another thread loops over the elements with for (User user : listUser) causing the error.此操作可能会发生,而另一个线程使用for (User user : listUser)循环遍历元素,导致错误。

When you exchange the ArrayList with a CopyOnWriteArrayList, the list.add(user) internally makes a copy and adds the new user into the copy.当您将 ArrayList 与 CopyOnWriteArrayList 交换时, list.add(user)内部创建一个副本并将新用户添加到副本中。 Therefore, a potentially running iteration is not affected since it loops over the old version of the array.因此,潜在的运行迭代不会受到影响,因为它会遍历数组的旧版本。 So the running iteration will ignore the new value.所以运行迭代将忽略新值。 Any new iterator will include the new value.任何新的迭代器都将包含新值。

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

相关问题 遍历List时发生ConcurrentModificationException - ConcurrentModificationException when iterate through List 尝试迭代HashMap时接收ConcurrentModificationException - Receiving ConcurrentModificationException when attempting to iterate through HashMap 当我在ArrayList上迭代时出现ConcurrentModificationException - ConcurrentModificationException when I iterate on ArrayList 迭代ArrayList时出现ConcurrentModificationException <Integer> - ConcurrentModificationException when iterating through an ArrayList <Integer> 在 WebLogic 中循环从 JPA 中的列表时出现 ConcurrentModificationException - ConcurrentModificationException when looping through lists from JPA in WebLogic 遍历集合,在循环中删除对象时避免 ConcurrentModificationException - Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop 使用迭代器时出现ConcurrentModificationException - ConcurrentModificationException when using iterators 发布 object 时出现 ConcurrentModificationException - ConcurrentModificationException when post a object 为什么ConcurrentModificationException仅在迭代循环中发生 - Why ConcurrentModificationException occurred only at iterate loop 如何在避免ConcurrentModificationException的同时迭代HashMap - How to iterate over a HashMap while avoiding ConcurrentModificationException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM