ScalaDoc说明了关于concurrentMap:"已弃用(自版本2.10.0起)使用scala.collection.concurrent.Map
代替。"很遗憾,rest of the Scala docs尚未更新,仍引用concurrentMap
。
我尝试将concurrent.Map
混合到HashMap
中,结果如下:
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]
所以我们看到,除了简单的mixin之外,还必须实现一些方法。这是使用concurrent.Map
的最佳方式,还是有更好的方式?
答案 0 :(得分:41)
scala.collection.concurrent.Map
特征并不意味着与现有的可变Scala Map
混合以获取地图实例的线程安全版本。 SynchronizedMap
之前存在2.11
mixin,但现已弃用。
目前,Scala具有scala.collection.concurrent.TrieMap
接口的scala.collection.concurrent.Map
实现,但也可以包装Java类。
{1}},在2.10之前的版本中称为scala.collection.concurrent.Map
,界面用于:
希望从头开始实现您自己的并发线程安全scala.collection.mutable.ConcurrentMap
想要包装现有的Java并发映射实现:
E.g:
Map
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)
答案 1 :(得分:11)
除非您想自己实现并发可变哈希映射,否则必须使用scala.collection.concurrent.TrieMap
。
答案 2 :(得分:5)
直接取自此评论: https://stackoverflow.com/a/49689669/7082628
2018年,显然你可以这样做:
import java.util.concurrent.ConcurrentHashMap
val m: ConcurrentHashMap[String,MyClass] = new ConcurrentHashMap
答案 3 :(得分:3)
通过“简单混合”,也许你会问这个特质是否可以用作as shown here的装扮SynchronizedMap
,答案显然不是。
实现包括TrieMap
和Java ConcurrentMap
的包装器(其中有两个实现)。 (Java还提供ConcurrentSkipListSet
作为Set。)
另见this roll-your-own question。
如果您习惯这样做,他们会让您了解转换方面的内容:
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
答案 4 :(得分:2)
2021 年和 Scala 2.13 的更新:
在包装Java并发映射实现时需要使用不同的隐式转换:
import java.util.concurrent.ConcurrentHashMap
import scala.collection.concurrent
import scala.jdk.CollectionConverters._
val map: concurrent.Map[String, String] = new ConcurrentHashMap().asScala