我有一个静态hashMap,与多个线程共享。我根本没有迭代地图,只是使用get
,put
,remove
。从ConcurrentModificationException
安全吗?
该方法看起来像这样
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);
}
}
}
}
从
ConcurrentModificationException
安全吗?
从ConcurrentModificationException
安全。该异常仅由使用传统迭代器或分裂器迭代(在某种意义上)地图或其视图之一的方法抛出。
但是,由于HashMap
不是一个线程安全的类,如果你在没有适当的外部外部同步的情况下从多个线程使用它,就会发生不好的事情。这些包括(按照增加的不良顺序)
size()
方法。你的示例代码是不安全的...但你不会得到“快速失败”ConcurrentModificationException
。相反,您可能会在难以重现的“随机”时间内遇到无法解释的错误。
如果多个线程在get
上执行put
,remove
和HashMap
操作,没有正确的同步,一些不好的事情,比如size()报告丢失/丢失的条目,意外的NPE ......甚至可能发生无限循环。
HashMap documentation说 -
请注意,此实现不同步。如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。 (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)...
谢谢Stephen。