Scala concurrent.Map中混合的最佳实践
有关concurrentMap的说明如下:“已弃用(自版本2.10.0起)使用Scala concurrent.Map中混合的最佳实践,scala,concurrency,hashmap,Scala,Concurrency,Hashmap,有关concurrentMap的说明如下:“已弃用(自版本2.10.0起)使用scala.collection.concurrent.Map。”遗憾的是,尚未更新,仍然引用concurrentMap 我尝试将concurrent.Map混合到HashMap中,结果如下: scala> val mmap = new mutable.HashMap[String, String] with collection.concurrent.Map[String, String] <consol
scala.collection.concurrent.Map
。”遗憾的是,尚未更新,仍然引用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]
scala>val mmap=new mutable.HashMap[String,String]和collection.concurrent.Map[String,String]
:16:错误:无法创建对象,因为:
它有4个未执行的成员。
/**从匿名类$anon中可以看出,缺少的签名如下所示。
*为了方便起见,它们可用作存根实现。
*/
def putIfAbsent(k:String,v:String):选项[String]=???
def remove(k:String,v:String):布尔=???
def replace(k:String,v:String):选项[String]=???
def replace(k:String,oldvalue:String,newvalue:String):布尔=???
val mmap=new mutable.HashMap[String,String]和collection.concurrent.Map[String,String]
因此,我们看到,除了简单的mixin之外,还必须实现一些方法。这是使用
concurrent.Map
的最佳方法,还是有更好的方法?除非您想自己实现一个并发可变哈希映射,否则您必须通过“简单混合”使用scala.collection.concurrent.TrieMap,也许您在问这个特性是否可以用作,答案显然不是
实现包括TrieMap
和Java的ConcurrentMap
包装器(其中有两个实现)。(Java还提供了ConcurrentSkipListSet
as Set。)
另见
如果你已经习惯了的话,他们已经为你介绍了转化方面的内容:
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
scala>import java.util.concurrent_
导入java.util.concurrent_
scala>import collection.JavaConverters_
导入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()
刻度>毫米。更换(“五”,5)
res0:选项[Int]=无
scala>mm.getClass
res1:Class[\up>scala.collection.concurrent.Map
特性并不意味着要与现有的可变scalaMap
混合以获得Map实例的线程安全版本。SynchronizedMap
mixin在2.11
之前就已经存在,但现在已被弃用
目前,Scala为Scala.collection.concurrent.TrieMap
接口提供了Scala.collection.concurrent.TrieMap
实现,但也可以包装Java类
在2.10之前的版本中,称为scala.collection.mutable.ConcurrentMap
的scala.collection.ConcurrentMap
接口在以下情况下使用:
- 想从头开始实现自己的并发线程安全
Map
- 要包装现有Java并发映射实现:
例如:
- 希望编写可在并发映射中工作的通用代码,但不希望提交到特定的实现:
例如:
- 通过使用synchronized,您可以围绕单线程可变映射实现实现自己的包装器(但是您需要确保您的程序仅通过该包装器访问可变映射,而不是直接访问)
例如:
直接摘自该评论:
2018年,显然你可以做到这一点:
import java.util.concurrent.ConcurrentHashMap
val m: ConcurrentHashMap[String,MyClass] = new ConcurrentHashMap
2021年和Scala 2.13的更新:
包装Java并发映射实现时,需要使用不同的隐式转换:
import java.util.concurrent.ConcurrentHashMap
导入scala.collection.concurrent
导入scala.jdk.CollectionConverters_
val-map:concurrent.map[String,String]=新的ConcurrentHashMap().asScala
关于并发HashSet和WeakHashMap呢?我不明白你在问什么。我在其他地方看到过这个用中缀符号编写的示例。关于HashSet和WeakHashMap的并发版本呢?它们已经实现了吗?或者有没有办法将行为混合到单线程版本中?我更喜欢在单个线程上进行同步键,而不是同步整个集合scala 2.11不赞成同步的traitsscala.collection.mutable.ConcurrentMap也不赞成使用scala.collection.concurrent.Map;进行此更改会弄乱解决方案的其余部分,您可以解释一下吗?您可以用ConcurrentMap替换ConcurrentMape> 在上面的例子中,没有?我是ConcurrentMap
和concurrent.Map
trait的作者,我很确定它确实有效。也许上面的代码中有一些拼写错误,但除非你告诉我更多关于哪些不起作用的内容,否则我无法帮助:(从2.12开始,我们应该使用import scala.collection.JavaConverters.\u
,scala.collection.convert.decorateAsScala.\u
不推荐使用
import scala.collection._
def foo(map: concurrent.Map[String, String]) = map.putIfAbsent("", "")
foo(new concurrent.TrieMap)
foo(new java.util.concurrent.ConcurrentSkipListMap().asScala)
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.
}
import java.util.concurrent.ConcurrentHashMap
val m: ConcurrentHashMap[String,MyClass] = new ConcurrentHashMap