It is possible to use
lock-free techniques with ConcurrentMaps because they include methods of a
sufficiently high consensus number, namely infinity, meaning that any number of Threads may be coordinated. This example could be implemented with the Java 8 merge() but it shows the overall lock-free pattern, which is more general. This example is not related to the internals of the ConcurrentMap but to the client code's use of the ConcurrentMap. For example, if we want to multiply a value in the Map by a constant C atomically: static final long C = 10; void atomicMultiply(ConcurrentMap map, long key) { while (true) { Long oldValue = map.get(key); // Assuming oldValue is not null. This is the 'payload' operation, and should not have side-effects due to possible re-calculation on conflict Long newValue = oldValue * C; if (map.replace(key, oldValue, newValue)) { break; } } } The putIfAbsent(k, v) is also useful when the entry for the key is allowed to be absent. This example could be implemented with the Java 8 compute() but it shows the overall lock-free pattern, which is more general. The replace(k, v1, v2) does not accept null parameters, so sometimes a combination of them is necessary. In other words, if v1 is null, then putIfAbsent(k, v2) is invoked, otherwise replace(k, v1, v2) is invoked. void atomicMultiplyNullable(ConcurrentMap map, long key) { while (true) { long oldValue = map.get(key); // This is the 'payload' operation, and should not have side-effects due to possible re-calculation on conflict long newValue = oldValue == null ? INITIAL_VALUE : oldValue * C; if (replaceNullable(map, key, oldValue, newValue)) { break; } } } static boolean replaceNullable(ConcurrentMap map, long key, long v1, long v2) { return v1 == null ? map.putIfAbsent(key, v2) == null : map.replace(key, v1, v2); } == History ==