我只是在内存中使用虚假数据库模拟api并使用scala.collection.mutable.HashMap[Int, AnyRef]
哪个是支持并发插入的最佳集合?还有更好的选择吗?
假设我需要另一种类似Map[Int, AnyRef]
的集合,但这次需要对键进行排序。
TreeMap是最好的选择吗?
提前致谢
答案 0 :(得分:1)
哪个是支持并发插入的最佳集合?还有更好的选择吗?
使用不可变数据结构
TreeMap是最好的选择吗?
是
实现线程安全的直接方法是使用不可变数据 结构。
Scala提供不可变的数据结构。只需导入scala.collection.immutable._
。
要使用scala.collection.immutable.TreeMap
This post tells about how to use TreeMap and provide custom ordering
答案 1 :(得分:0)
这里有两个选择。
您可以使用scala.collection.immutable.HashMap
之类的不可变数据结构,它提供高效的不可变哈希映射。您还需要记住,对此地图的每次更新都需要像这样同步:
object Database {
private var map = new immutable.HashMap[Int, AnyRef]
def get(index: Int) = map(index)
def insert(index: Int, value: AnyRef) =
synchronized(map = map.updated(index, value))
}
另一种方法是使用并发可变地图,例如scala.collection.concurrent.TrieMap
,它不需要额外的锁定:
object Database {
private val map = new concurrent.TrieMap[Int, AnyRef]
def get(index: Int) = map(index)
def insert(index: Int, value: AnyRef) = map.put(index, value)
}
答案 2 :(得分:0)
我不同意上述建议。无论如何你都要有可变状态,最好在数据容器内隔离它,而不是每次都更换容器本身。
最好为此目的使用java容器。对于hashmap,java ConcurrentHashMap
是您的最佳选择。对于已排序的实现,您必须明确同步:
object DB {
import java.util._
val hashed = new concurrent.ConcurrentHashMap[String, AnyRef]
val sorted = Collections.synchronizedMap(new TreeMap[Int, AnyRef])
}
你可以import scala.collection.JavaConversions._
隐式地将这些转换为scala地图,以获得好处,例如map
,filter
等,但是...... 你可能不应该} EM>。在99%的情况下,使用其中任何一个在并发下都不是一个好主意。除了常规get
和put
(以及put/computeIfNotExists
案例的ConcurrentHashmap
)原语之外的任何内容都是非常重要的,并且使用起来很危险。
将这些视为原始的键值容器,而不是完整的scala集合。