Original Question is here,但这次情况略有不同。
我有一个静态hashMap,与多个线程共享。我不是在迭代地图,也不在乎地图的大小。我仅在地图中使用get
,put
,remove
。每个线程可以调用someClass.track(true)
或someClass.track(false)
。我想跟踪线程何时为每个线程进入方法(递增#)并退出方法(递减#)。
仅使用HashMap是否足够?还是我必须使用ConcurrentHashMap来保证从track
方法中获取正确的值?
方法看起来像这样
private static Map<Long, Integer> TRACKER = new HashMap<Long,Integer>();
public static Integer track(boolean b) {
long tid = Thread.currentThread().getId();
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);
}
}
}
return TRACKER.get(tid);
}
答案 0 :(得分:2)
您可以在阅读地图时对其进行修改。因此,至少由于这个原因,您应该考虑使用ConcurrentHashMap
或使用显式同步机制,因为HashMap
并非旨在以这种方式使用:
请注意,此实现未同步。如果有多个线程 同时访问哈希映射,并且至少有一个线程 在结构上修改地图,必须在外部进行同步。
或使用ConcurrentHashMap
。
请注意,ConcurrentHashMap
可能不合适,因为您想根据时间轴在特定时刻获取与键关联的值。与ConcurrentHashMap
一样,检索操作也不会阻塞,它们反映了最后的“已知信息”,即not necessarily the last chronological information:
检索操作(包括get)通常不会阻塞,因此可能 与更新操作(包括放置和删除)重叠。检索 反映最近完成的更新操作的结果 保持发病。
通常,在I
时刻获得确切信息实际上取决于您的要求。您无需解释您的内容,但无论如何,都没有关系,因为根据您的实际代码,该方法由不操纵相同键/值的线程并发访问。因此,这种ConcurrentHashMap
的特殊性不是问题。
因此,ConcurrentHashMap
似乎是一个非常好的用例。