The ScalaDoc says this about concurrentMap: \"Deprecated (Since version 2.10.0) Use scala.collection.concurrent.Map
instead.\" Unfortunately, the rest of the Scala
Update for 2021 and Scala 2.13:
You need to use different implicit conversion when wrapping the Java concurrent map implementation:
import java.util.concurrent.ConcurrentHashMap
import scala.collection.concurrent
import scala.jdk.CollectionConverters._
val map: concurrent.Map[String, String] = new ConcurrentHashMap().asScala
Unless you want to implement a concurrent mutable hash map yourself, you have to use scala.collection.concurrent.TrieMap
.
Taken from this comment directly: https://stackoverflow.com/a/49689669/7082628
In 2018, apparently you can just do this:
import java.util.concurrent.ConcurrentHashMap
val m: ConcurrentHashMap[String,MyClass] = new ConcurrentHashMap
The scala.collection.concurrent.Map
trait is not meant to be mixed-in with an existing mutable Scala Map
to obtain a thread-safe version of the map instance. The SynchronizedMap
mixin existed for this purpose before 2.11
, but is now deprecated.
Currently, Scala has the scala.collection.concurrent.TrieMap
implementation for the scala.collection.concurrent.Map
interface, but can wrap Java classes as well.
The scala.collection.concurrent.Map
, in versions prior to 2.10 known as scala.collection.mutable.ConcurrentMap
, interface is used when you:
want to implement your own concurrent, thread-safe Map
from scratch
want to wrap an existing Java concurrent map implementation:
E.g:
import scala.collection._
import scala.collection.convert.decorateAsScala._
import java.util.concurrent.ConcurrentHashMap
val map: concurrent.Map[String, String] = new ConcurrentHashMap().asScala
E.g.:
import scala.collection._
def foo(map: concurrent.Map[String, String]) = map.putIfAbsent("", "")
foo(new concurrent.TrieMap)
foo(new java.util.concurrent.ConcurrentSkipListMap().asScala)
E.g.:
class MySynchronizedMap[K, V](private val underlying: mutable.Map[K, V])
extends concurrent.Map[K, V] {
private val monitor = new AnyRef
def putIfAbsent(k: K,v: V): Option[String] = monitor.synchronized {
underlying.get(k) match {
case s: Some[V] => s
case None =>
underlying(k) = v
None
}
}
def remove(k: K, v: V): Boolean = monitor.synchronized {
underlying.get(k) match {
case Some(v0) if v == v0 => underlying.remove(k); true
case None => false
}
}
// etc.
}
By "simple mixin", perhaps you're asking if the trait can be used as a decorator as shown here for SynchronizedMap, and the answer is apparently not.
Implementations include TrieMap
and the wrapper for Java's ConcurrentMap
(of which there are two implementations). (Java also offers ConcurrentSkipListSet
as Set.)
Also see this roll-your-own question.
They have you covered on the conversion side of things, if that's what you were used to:
scala> import java.util.concurrent._
import java.util.concurrent._
scala> import collection.JavaConverters._
import collection.JavaConverters._
scala> val m = new ConcurrentHashMap[String, Int]
m: java.util.concurrent.ConcurrentHashMap[String,Int] = {}
scala> val mm = m.asScala
mm: scala.collection.concurrent.Map[String,Int] = Map()
scala> mm.replace("five",5)
res0: Option[Int] = None
scala> mm.getClass
res1: Class[_ <: scala.collection.concurrent.Map[String,Int]] = class scala.collection.convert.Wrappers$JConcurrentMapWrapper