我想使用基于比较器的键值映射。这将具有读物和罕见的写作操作(每3个月一次通过调度程序)。集合的初始负载将在应用程序启动时完成。另请注意,写作将:
- 向地图添加一个条目
- 不会修改地图的任何现有条目。
将confurnentskiplistmap成为这一点的好候选人。在此操作是否可以同时访问多个线程?我正在寻找并发的非阻止阅读,但原子写作。
ConcurrentHashMap
正是您要寻找的。来自Javadoc:
检索操作(包括GET)通常不会阻止,因此可能与更新操作(包括放置和删除)重叠。检索反映了最新完成的更新操作的结果。(更正式地,给定密钥的更新操作发生在与任何(非零)检索之前的关系之前,该密钥报告更新值。)
听起来它满足了您对"并发非阻止阅读但原子写作"的要求。
由于您的写作很少,因此您可能需要在创建confurrenthashmap时指定高负载依赖器和适当的初始分配,这将在填充地图时阻止表调整大小,尽管这充其量是一个适度的好处。(尽管Java 8的Javadoc似乎意味着不再用作尺寸提示。)
如果您绝对必须具有 a SortedMap
或 NavigableMap
,则 ConcurrentSkipListMap
是即可进行的。但是我会仔细检查您实际上需要这些接口提供的功能(获取第一个/最后一个键,子包,查找附近的条目等)。您将支付陡峭的价格(大多数操作中的log n vs.恒定时间)。
由于您正在寻找并发操作,因此您基本上有3个竞争对手。hashtable,confurrenthashmap,concurrentsKiplistMap(或collections.synchronizedmap(),但这不是有效的)。
- 在这3个后2中,它们更适合并发操作,因为它们只是锁定地图的一部分,而不是像Hashtable一样锁定整个地图。
- 后两个SkiplistMap使用跳过列表数据结构,可确保快速搜索和各种操作的平均o(log n)性能。
- 它还提供了confurrenthashmap无法的操作数量,即coilingentry/key(),floaterentry/key()等。它还维护了一个排序订单,否则必须计算出来。
因此,如果您仅要求进行更快的搜索,我会建议使用confurnthashmap,但是由于您还提到了"稀有写操作"one_answers"所需的分类"顺序,所以我认为 concurrentsKiplistMapmap 赢得了比赛。
如果您愿意尝试第三方代码,则可以考虑使用抄写版的地图,这对于不经常写作是理想的。这是通过谷歌搜索出来的:
https://bitbucket.org/atlassian/atlassian-util-concurrent/wiki/copyonwrite maps
我自己从未尝试过如此警告。