如果我仅以线程ID为键调用get,put,remove,并且从不迭代地图,是否需要ConcurrentHashMap?

时间:2018-09-07 17:50:37

标签: java concurrency hashmap

Original Question is here,但这次情况略有不同。

我有一个静态hashMap,与多个线程共享。我不是在迭代地图,也不在乎地图的大小。我仅在地图中使用getputremove。每个线程可以调用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);
  }

1 个答案:

答案 0 :(得分:2)

您可以在阅读地图时对其进行修改。因此,至少由于这个原因,您应该考虑使用ConcurrentHashMap或使用显式同步机制,因为HashMap并非旨在以这种方式使用:

  

请注意,此实现未同步。如果有多个线程   同时访问哈希映射,并且至少有一个线程   在结构上修改地图,必须在外部进行同步。

或使用ConcurrentHashMap

请注意,ConcurrentHashMap可能不合适,因为您想根据时间轴在特定时刻获取与键关联的值。与ConcurrentHashMap一样,检索操作也不会阻塞,它们反映了最后的“已知信息”,即not necessarily the last chronological information

  

检索操作(包括get)通常不会阻塞,因此可能   与更新操作(包括放置和删除)重叠。检索   反映最近完成的更新操作的结果   保持发病。

通常,在I时刻获得确切信息实际上取决于您的要求。您无需解释您的内容,但无论如何,都没有关系,因为根据您的实际代码,该方法由不操纵相同键/值的线程并发访问。因此,这种ConcurrentHashMap的特殊性不是问题。
因此,ConcurrentHashMap似乎是一个非常好的用例。