Search code examples
javamultithreadingconcurrenthashmap

Java CHM synchronisation


Following up on this question (Java thread safety - multiple atomic operations?), I don't want to add more questions to it, but now I have this doubt:

private final Map<String, Set<String>> data = Maps.newConcurrentMap();

... then in a method ...

if (data.containsKey("A")) {
    data.get("A").add("B");
}

It should be something like this:

synchronized(data) {
    if (data.containsKey("A")) {
        data.get("A").add("B");
    }
}

In order to be thread-safe. Is that correct?

So operations are atomic, but combining them would require synchronisation, is that right? At that point, would it make sense to just use a simple HashMap instead of a concurrent one, as we're manually handling sync?

Is there any method in CHM to make this work atomically?


Solution

  • In your specific case, you might want to use computeIfPresent method of ConcurrentHashMap:

    data.computeIfPresent("A", (k, v) -> { v.add("B"); return v; } );
    

    From the javadocs:

    If the value for the specified key is present, attempts to compute a new mapping given the key and its current mapped value. The entire method invocation is performed atomically.

    So there's no need for explicit synchronization.