[英]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
.我根本没有迭代地图,而只是使用
get
、 put
、 remove
。 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
上执行get
、 put
和remove
操作,而没有适当的同步,一些不好的事情,如 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)这些包括(按坏处递增的顺序)
size()
method reporting the wrong value. size()
方法报告错误的值。 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.