在Scala concurrent.Map中混合的最佳实践 [英] Best practices for mixing in Scala concurrent.Map
问题描述
ScalaDoc 对concurrentMap说:已弃用(从版本2.10.0开始)使用 scala.collection.concurrent.Map
。很抱歉,其他Scala文档尚未更新仍然引用 concurrentMap
。
我试图混合在 concurrent.Map
转换为 HashMap
,结果如下:
Scala> val mmap = new mutable.HashMap [String,String] with collection.concurrent.Map [String,String]
< console>:16:error:对象创建不可能,因为:
它有4未实现成员。
/ **从匿名类$ anon可以看出,缺少的签名如下。
*为了方便,这些可用作存根实现。
* /
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]
所以我们看到,而不是一个简单的混合,一些方法也必须实现。这是使用 concurrent.Map
的最好方法,还是有更好的方法?
scala.collection.concurrent.Map
trait不意味着与现有的可变Scala混合 Map
以获取地图实例的线程安全版本。 SynchronizedMap
mixin在 2.11
之前存在,但现已废弃。
目前,Scala对 scala.collection.concurrent.Map $实现
scala.collection.concurrent.TrieMap
实现c $ c> interface
scala.collection.concurrent.Map
,在2.10之前的版本称为 scala.collection.mutable.ConcurrentMap
,当您使用接口时:
-
希望从头开始实现自己的并发,线程安全
映射
-
想要包装现有的Java并发地图实现:
例如:
import scala.collection._
import scala.collection.convert.decorateAsScala._
import java.util.concurrent.ConcurrentHashMap
val map:concurrent.Map [String,String] = new ConcurrentHashMap()。asScala
$ b b
- 要写出能够同时处理地图的通用代码,并且不想提交到特定实现:
例如:
import scala.collection._
def foo :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无=>
underlying(k)= v
无
}
}
def remove(k:K,v:V):Boolean = monitor.synchronized {
underlying.get(k)match {
case Some(v0)if v == v0 => underlying.remove(k); true
case无=> false
}
}
//等
}
The ScalaDoc says this about concurrentMap: "Deprecated (Since version 2.10.0) Use scala.collection.concurrent.Map
instead." Unfortunately, the rest of the Scala docs has not been updated and still references concurrentMap
.
I tried to mix in concurrent.Map
into a HashMap
, with the following results:
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]
So we see that instead of a simple mixin, some methods must also be implemented. Is this the best way to use concurrent.Map
, or is there a better way?
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 scratchwant 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
- want to write generic code that works concurrent maps, and don't want to commit to a specific implementation:
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)
- you could implement your own wrapper around a single-threaded mutable map implementation by using synchronized (but you would need to ensure that your program is accessing the mutable map only through this wrapper and never directly).
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.
}
这篇关于在Scala concurrent.Map中混合的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!