简体   繁体   English

可以在没有迭代的情况下在 HashMap 中获取、放置和删除元素导致 ConcurrentModificationException?

[英]Can get, put & remove element in HashMap without iteration cause ConcurrentModificationException?

I have a static hashMap, shared with multiple threads.我有一个静态 hashMap,与多个线程共享。 I am not iterating the map at all but just uses the get , put , remove .我根本没有迭代地图,而只是使用getputremove Is it safe from ConcurrentModificationException ? ConcurrentModificationException是否安全?

The method looks like this该方法看起来像这样

private static Map<Long, Integer> TRACKER = new HashMap<Long,Integer>();
public static void track(Long tid, boolean b) {
        if (b) {
            if (TRACKER.containsKey(tid)) {
                TRACKER.put(tid, TRACKER.get(tid) + 1);
            } else {
                TRACKER.put(tid, 1);
            }
        } else {
            Integer n = TRACKER.get(tid);
            if (n != null) {
                n = n -1;
                if (n == 0) {
                    TRACKER.remove(tid);
                } else {
                    TRACKER.put(tid, n);
                }
            }
        }
    }

If multiple threads are performing get , put & remove operations on a HashMap , without proper synchronization, some bad things like size() reporting missing / lost entries, unexpected NPEs ... even infinite loops may happen.如果多个线程在HashMap上执行getputremove操作,而没有适当的同步,一些不好的事情,如 size() 报告丢失/丢失的条目、意外的 NPE ......甚至可能发生无限循环。

HashMap documentation says - HashMap 文档说 -

Note that this implementation is not synchronized.请注意,此实现不同步。 If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally.如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。 (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) ... (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。) ...

Thanks Stephen.谢谢斯蒂芬。

Is it safe from ConcurrentModificationException ? ConcurrentModificationException是否安全?

It is safe from ConcurrentModificationException .它不受ConcurrentModificationException的影响。 That exception is only thrown by methods that iterate (in some sense) the map or one of its views using a conventional iterator or a spliterator.该异常仅由使用常规迭代器或拆分器迭代(在某种意义上)地图或其视图之一的方法引发。

However, since HashMap is not a thread-safe class, if you use it from multiple threads without proper external external synchronization, bad things can happen.但是,由于HashMap不是线程安全的类,如果在没有适当的外部外部同步的情况下从多个线程中使用它,可能会发生不好的事情。 These include (in order of increasing badness)这些包括(按坏处递增的顺序)

  1. The size() method reporting the wrong value. size()方法报告错误的值。
  2. Entries mysteriously disappearing, either temporarily or permanently.条目神秘消失,暂时或永久。
  3. Possible NPEs and other unchecked exceptions.可能的 NPE 和其他未经检查的异常。
  4. Possible infinite loops due to an unfortunate sequence of operations by multiple threads creating a loop in a hash chain.由于多个线程在哈希链中创建循环的不幸操作序列,可能导致无限循环。

Your example code is unsafe ... but you won't get a "fast fail" ConcurrentModificationException .您的示例代码不安全......但您不会得到“快速失败” ConcurrentModificationException Instead you are likely to get inexplicable errors at "random" times that are difficult to reproduce.相反,您可能会在难以重现的“随机”时间遇到莫名其妙的错误。

暂无
暂无

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

相关问题 如何在没有ConcurrentModificationException的情况下删除哈希图中的多个映射? - How to remove multiple mappings in hashmap without ConcurrentModificationException? 如何在没有ConcurrentModificationException的情况下删除List迭代 - How to remove List iteration without ConcurrentModificationException 可以更改HashMap的值的成员导致java.util.ConcurrentModificationException - Can changing members of values of HashMap cause java.util.ConcurrentModificationException 如何在迭代Hashmap时获取ConcurrentModificationException? - How I can get ConcurrentModificationException while iterating Hashmap? Java中的ConcurrentModificationException即使没有迭代 - ConcurrentModificationException in java even without iteration 如果从多个线程中使用,则HashMap#put / remove是否会遇到任何ConcurrentModificationException - Will HashMap#put/remove suffer any ConcurrentModificationException if used from multiple threads 将新元素放入 HashMap 时发生 ConcurrentModificationException - ConcurrentModificationException during putting new element into HashMap HashMap迭代/删除获取java.util.ConcurrentModificationException - HashMap iteration/removal getting java.util.ConcurrentModificationException HashMap中的ConcurrentModificationException - ConcurrentModificationException in HashMap 如何从哈希图中使用jstl在jsp中获取值而不进行迭代? - how to get values in jsp using jstl from hashmap without iteration?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM