1

Original Question is here but this time slightly different scenario.

I have a static hashMap, shared with multiple threads. I am not iterating the map and don't care about the size of the map. I only use the get, put, remove in the map. Each thread may call someClass.track(true) or someClass.track(false). I want to track when a thread enters a method (increment #) and exit a method (decrements #) for each thread.

Is it sufficient to use just a HashMap? Or I have to use a ConcurrentHashMap to guarantee getting a correct value from the track method?

The method looks like this

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);
  }
Anthony C
  • 2,117
  • 2
  • 15
  • 26
  • here is the [answer to the question](https://stackoverflow.com/a/52213856/9949315) – Maxim Sep 07 '18 at 18:19
  • @Anthony C You should focus on the requirement as you ask your question. According to the old question, you try to guess very specific issues that may never happen. But this question is already much clearer. – davidxxx Sep 07 '18 at 18:46
  • It's something very simple, it tracks # of calls enter some specific methods (possibly recursive) per thread. It calls `track(true) ` at the first line of the method and call `track(false)` at the last line of the method – Anthony C Sep 07 '18 at 18:57
  • I thought the answers to the previous question did a perfectly adequate job of telling you this was dangerously broken, complete with references to the api doc that says not to do this. what is left that needs clarifying? – Nathan Hughes Sep 07 '18 at 19:43
  • @NathanHughes, just wanted to know if ConcurrentHashMap is enough to fix it or need something more. – Anthony C Sep 07 '18 at 20:02

1 Answers1

2

You may modify the map while you read it. So for at least this reason you should consider to use ConcurrentHashMap or use an explicit synchronization mechanism as HashMap is not designed to be used in this way :

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.

Or use ConcurrentHashMap.

Note that ConcurrentHashMap may not fit as you want to get the value associated to a key at a specific instant according to the timeline. As with ConcurrentHashMap, retrieval operations are not blocking, these reflect the last "known information" that is not necessarily the last chronological information :

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset.

In a general way, having the exact information at the I instant depends really on your requirement. You don't explain yours but whatever, it doesn't matter because according to your actual code, the method is accessed concurrently by threads that don't manipulate the same key/value. So, this ConcurrentHashMap particularity is not a problem.
So it seems a very good use case for ConcurrentHashMap.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • You say `thread B with the same tid can enter the same statement`. If tid is actually a thread id as he says, how could this happen? You would need to have multiple threads with the same id right? – Eric Petroelje Sep 07 '18 at 18:04
  • 1
    @Eric Petroelje I though of the same thing. I rewrited my answer. While as the OP performs concurrent reading/writing on the Map, the synchronization remains needed. – davidxxx Sep 07 '18 at 18:15