实现并发LinkedHashMap

我正在尝试为multithreading架构创建并发LinkedHashMap。

如果我使用Collections#synchronizedMap() ,我将不得不使用synchronized块进行迭代。 这种实现将导致元素的顺序添加。

如果我使用ConcurrentSkipListMap有任何方法可以实现Comparator按顺序存储,如存储在Linked List或队列中。

我想使用java内置而不是第三方软件包。

编辑:

在这个并发的LinkedHashMap ,如果键是名称,我希望按顺序放置键。 即,新值将在开始或结束时附加到,但是顺序地附加。

迭代时, LinkedHashMap可以添加新条目,也可以删除。 但迭代应该是添加条目的顺序。

我理解通过使用Collections#synchronizedMap() ,必须实现用于迭代的同步块,但是在迭代时地图是可修改的(可以添加/删除条目)。

如果使用synchronizedMap,则不必在外部进行同步,迭代除外。 如果需要保留地图的顺序,则应使用SortedMap。 您可以使用ConcurrentSkipListMap(它是线程安全的)或另一个SortedMap与synchronizedSortedMap结合使用。

LinkedHashMap具有通过哈希表运行的双向链表。 FIFO仅在写入(插入或移除)时改变链接。 这使得实现版本相当简单。

  1. 写一个只允许插入顺序的LHM。
  2. 切换到ConcurrentHashMap作为哈希表。
  3. 使用锁保护#put() / #putIfAbsent() / #remove()
  4. 使“下一个”字段易变。

在迭代时,不需要锁定,因为您可以安全地遵循“下一个”字段。 只需在#get()上委托给CHM,读取就可以无锁定。

使用Collections#synchronizedMap()

根据我的观点,如果我使用Collections.synchronizedMap(),我将不得不使用synchronized块作为getter / setter。

这不是真的。 您只需要在任何视图(键集,值,条目集)上同步迭代。 另请参阅abovelinked API文档。

到目前为止,我的项目使用了Apache Collections的LRUMap,但它基于SequencedHashMap。 集合提出了ListOrderedMap,但没有一个是线程安全的。

我已从Google Guava切换到MapMaker 。 您也可以查看CacheBuilder 。

嗯,简单的答案是使用Comparator器操作的单调增加的密钥提供程序。 想想AtomicInteger ,每次插入时,都会创建一个用于比较的新密钥。 如果您汇集真实密钥,则可以创建OrderedKey的内部映射。

 class OrderedKey implements Comparable> { T realKey; int index; OrderedKey(AtomicInteger source, T key) { index = source.getAndIncrement(); realKey = key; } public int compareTo(OrderedKey other) { if (Objects.equals(realKey, other.realKey)) { return 0; } return index - other.index; } } 

这样可以避免使用自定义比较器,并为您提供一个很好的O(1)方法来计算大小(除非你允许删除,在这种情况下,也要计算这些,所以你可以从“减去”所有成功的删除)所有成功添加“,成功意味着实际创建或删除了一个条目”。