ScalaDoc dit ceci à propos de concurrentMap: "Obsolète (depuis la version 2.10.0) Utilisez scala.collection.concurrent.Map
à la place. "Malheureusement, le reste des documents Scala n'a pas été mis à jour et fait toujours référence à concurrentMap
.
J'ai essayé de mélanger concurrent.Map
dans un HashMap
, avec les résultats suivants:
scala> val mmap = new mutable.HashMap[String, String] with collection.concurrent.Map[String, String]
<console>:16: error: object creation impossible, since:
it has 4 unimplemented members.
/** As seen from anonymous class $anon, the missing signatures are as follows.
* For convenience, these are usable as stub implementations.
*/
def putIfAbsent(k: String,v: String): Option[String] = ???
def remove(k: String,v: String): Boolean = ???
def replace(k: String,v: String): Option[String] = ???
def replace(k: String,oldvalue: String,newvalue: String): Boolean = ???
val mmap = new mutable.HashMap[String, String] with collection.concurrent.Map[String, String]
On voit donc qu'au lieu d'un simple mixin, certaines méthodes doivent également être implémentées. Est-ce la meilleure façon d'utiliser concurrent.Map
, ou existe-t-il un meilleur moyen?
Le scala.collection.concurrent.Map
trait est non destiné à être mélangé avec un mutable existant Scala Map
pour obtenir une version thread-safe de l'instance de carte. Le mixage SynchronizedMap
existait à cet effet avant 2.11
, mais est désormais obsolète.
Actuellement, Scala a le scala.collection.concurrent.TrieMap
implémentation pour le scala.collection.concurrent.Map
interface, mais peut encapsuler Java classes également.
Le scala.collection.concurrent.Map
, dans les versions antérieures à 2.10 appelées scala.collection.mutable.ConcurrentMap
, l'interface est utilisée lorsque vous:
souhaitez implémenter votre propre Map
simultané et sans fil
souhaitez encapsuler une implémentation de carte simultanée existante Java:
Par exemple:
import scala.collection._
import scala.collection.convert.decorateAsScala._
import Java.util.concurrent.ConcurrentHashMap
val map: concurrent.Map[String, String] = new ConcurrentHashMap().asScala
Par exemple.:
import scala.collection._
def foo(map: concurrent.Map[String, String]) = map.putIfAbsent("", "")
foo(new concurrent.TrieMap)
foo(new Java.util.concurrent.ConcurrentSkipListMap().asScala)
Par exemple.:
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.
}
À moins que vous ne souhaitiez implémenter vous-même une carte de hachage mutable simultanée, vous devez utiliser scala.collection.concurrent.TrieMap
.
Tiré de ce commentaire directement: https://stackoverflow.com/a/49689669/7082628
En 2018, apparemment, vous pouvez simplement faire ceci:
import Java.util.concurrent.ConcurrentHashMap
val m: ConcurrentHashMap[String,MyClass] = new ConcurrentHashMap
Par "simple mixin", vous demandez peut-être si le trait peut être utilisé comme décorateur comme indiqué ici pour SynchronizedMap
, et la réponse est apparemment ne pas.
Les implémentations incluent TrieMap
et l'encapsuleur pour Java ConcurrentMap
(dont il existe deux implémentations). (Java propose également ConcurrentSkipListSet
comme Set.)
Voir aussi cette question à rouler .
Ils vous couvrent du côté de la conversion, si c'est ce à quoi vous étiez habitué:
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