How to make atomic updates with TrieMap and ConcurrentHashMap?

2

In Java ConcurrentHashMap has an interesting property . Operations such as putIfAbsent , remove , replace , computeIfAbsent , computeIfPresent , compute , and merge are atomic.

Example:

final Map<String, Integer> map = new ConcurrentHashMap<>();
IntStream.rangeClosed(1, 10000)
         .parallel()
         .forEach(i -> map.merge("key" + (i % 5 + 1), i, Integer::sum));
final long total = map.values().stream().mapToInt(Integer::intValue).sum(); // 50005000

I did not find any similar operation in the API TrieMap :

val map = TrieMap[String, Int]().withDefaultValue(0)
(1 to 10000).par.foreach(i => map(s"key${i % 5 + 1}") += i)
val total = map.values.sum // valor aleatório, += não é uma operação atomica

You can clearly synchronize operations manually as well as use constructs such as CAS , STM , etc:

(1 to 10000).par.foreach(i => {
  val key = s"key${i % 5 + 1}".intern
  key.synchronized {
    map(key) += i
  }
})

Alternatively, you can use ConcurrentHashMap of Java directly (without using asScala ):

val map = new java.util.concurrent.ConcurrentHashMap[String, Int]()
(1 to 10000).par.foreach(i => map.merge(s"key${i % 5 + 1}", i, Integer.sum _))
val total = map.values().asScala.sum  

Is there any simpler / idiomatic way of securing atomic updates in a concurrent.Map ?

    
asked by anonymous 28.03.2018 / 15:03

0 answers