28

I need a mutable thread safe Map and a mutable thread safe List in Scala. I know that the immutable collections are thread safe by default. But, I need to update my collections very often because of which I couldn't use immutable. Also I need my threadsafe mutable Map to maintain the insertion order.

Right now am using the map below

val map = scala.collection.mutable.LinkedHashMap[String,Any]()

This map maintains the insertion order and is mutable. How do I make it thread safe?

3

3 Answers 3

46

Fast hint for those coming to this in 2018 or later:

import java.util.concurrent.ConcurrentHashMap

val m: ConcurrentHashMap[String,MyClass] = new ConcurrentHashMap
2
  • 3
    Is it still valid in 2021? Commented Oct 17, 2021 at 12:36
  • 2
    Yes, it is valid. The "synchronized" collections in Scala are deprecated since Scala 2.11.0. It is recommended to use java.util.concurrent. package. Commented Jul 25, 2022 at 21:15
22

As was mentioned by AlexIv in his answer, there's a trait you can mix in if you want thread safety. There's another way though:

    val synchronizedMap = new scala.collection.mutable.LinkedHashMap[String, Any]() with scala.collection.mutable.SynchronizedMap[String, Any]

That should give you the map with synchronization on each access. Easy, but might not meet the performance requirements. If so, it would be probably easier to create a custom class extending the LinkedHashMap, mixing in the concurrent.Map trait (as was suggested) and provide the implementation of relevant methods, i.e: putIfAbsent, remove replace (2 overloads).

6
  • 21
    If you can stand a bit more work, use the synchronized method on the mutable collection directly where you need thread safety. It'll save you the performance hit that this mixin brings. E.g. someMap.synchronized { someMap += ("someKey", "anyValue") }
    – tysonjh
    Commented Mar 6, 2014 at 14:32
  • 12
    For anyone new viewing this, the SynchronizedMap trait has been deprecated as not safe enough. Recommends using Java thread safe collections. Commented Aug 20, 2015 at 1:20
  • 1
    It's a compiler warning when you build after mixing in this trait - not sure about a link Commented Oct 10, 2015 at 19:34
  • 4
    @Gepp: scala-lang.org/api/2.12.3/scala/collection/mutable/…: "(Since version 2.11.0) Synchronization via traits is deprecated as it is inherently unreliable. Consider java.util.concurrent.ConcurrentHashMap as an alternative." Commented Nov 8, 2017 at 22:13
  • 3
    TrieMap is mutable, thread-safe, lock-free, and is not deprecated
    – ianpojman
    Commented Nov 5, 2020 at 23:05
1

To elaborate on the comment for a Map you can use

import scala.collection.concurrent.TrieMap

Is not deprecated and is mutable and thread-safe.

It should drop in for your scala.collection.mutable.LinkedHashMap as they share the same interface of scala.collection.mutable.MapLike and scala.collection.mutable.Map

Sadly I don't know about the List

Not the answer you're looking for? Browse other questions tagged or ask your own question.