我想使用基于比较器的键值Map。这将具有读取和罕见的写入操作(通过调度程序每3个月一次)。集合的初始加载将在应用程序启动时完成。 另请注意,写入将:
ConcurrentSkipListMap是否适合这个。对此进行get操作是否允许同时访问多个线程?我正在寻找并发非阻塞读取但是原子写入。
答案 0 :(得分:1)
如果您愿意尝试第三方代码,您可以考虑写入时复制版本的地图,这对于不经常写入非常理想。这是通过谷歌搜索出现的一个:
https://bitbucket.org/atlassian/atlassian-util-concurrent/wiki/CopyOnWrite%20Maps
从未尝试过这样做,所以请注意。
答案 1 :(得分:0)
ConcurrentHashMap
正是您所寻找的。来自Javadoc:
检索操作(包括get)一般不会阻塞,因此可能与更新操作重叠(包括put和remove)。检索反映了最近完成的更新操作的结果。 (更正式地说,给定密钥的更新操作与报告更新值的该密钥的任何(非空)检索之前发生关系。)
听起来它满足了“并发非阻塞读取但原子写入”的要求。
由于你写的这么少,你可能想要指定一个high loadFactor and appropriate initialSize when creating the ConcurrentHashMap,这会在你填充地图时阻止表调整大小,尽管这是一个适度的好处。 (您也可以将concurrencyLevel设置为1,尽管Java 8的Javadoc似乎暗示不再将其用作大小调整提示。)
如果绝对必须 SortedMap
或NavigableMap
,那么ConcurrentSkipListMap
就是开箱即用的方式。但是在使用它们之前,我会仔细检查你确实需要这些接口提供的功能(获取第一个/最后一个键,子图,查找附近的条目等)。您将支付高昂的价格(对于大多数操作,记录n与恒定时间)。
答案 2 :(得分:0)
由于您正在寻找并发操作,因此您基本上有3个竞争对手。 Hashtable,ConcurrentHashMap,ConcurrentSkipListMap(或Collections.synchronizedMap()但效率不高)。
因此,如果您只是要求更快的搜索,我建议使用ConcurrentHashMap,但由于您还提到了'罕见的写操作'和'所需的排序'顺序,我认为 ConcurrentSkipListMap 赢得了比赛。