实现并发 LinkedHashMap
我正在尝试为多线程架构创建并发 LinkedHashMap。
如果我使用Collections#synchronizedMap()
,我将不得不使用同步块进行迭代。此实现将导致元素的顺序添加。
如果我使用 ConcurrentSkipListMap 是否有任何方法可以实现比较器来按顺序存储,如存储在链接列表或队列中。
我想使用内置的java而不是第三方包。
编辑:
在这个并发的 LinkedHashMap 中,如果键是名称,我希望按键到达的顺序放置键。即新值将附加到开始或结束处,但顺序。
迭代时,LinkedHashMap
可以添加新条目,也可以删除。但迭代应该是添加条目的顺序。
据我所知,通过使用Collections#synchronizedMap(),必须实现迭代的同步块,但是映射在迭代时是否可以修改(可以添加/删除条目)。
I'm trying to create a concurrent LinkedHashMap for a multithreaded architecture.
If I use Collections#synchronizedMap()
, I would have to use synchronized blocks for iteration. This implementation would lead to sequential addition of elements.
If I use ConcurrentSkipListMap
is there any way to implement a Comparator
to store sequentially, as stored in Linked List or queue.
I would like to use java's built in instead of third party packages.
EDIT:
In this concurrent LinkedHashMap
, if the keys are the name, I wish to put the keys in sequence of their arrival. i.e. new value would be appended to either at start or end, but sequentially.
While iterating, the LinkedHashMap
could be added with new entries, or removed. but the iteration should be the sequence in which the entries were added.
I understand that by using Collections#synchronizedMap()
, an synchronized block for iteration would have to be implemented, but would the map be modifiable (entries could be added/removed) while it is being iterated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果使用synchronizedMap,除了迭代之外,不需要进行外部同步。如果需要保留映射的顺序,则应使用 SortedMap。您可以使用线程安全的 ConcurrentSkipListMap,或另一个与 SynchronizedSortedMap 结合的 SortedMap。
If you use synchronizedMap, you don't have to synchronize externally, except for iteration. If you need to preserve the ordering of the map, you should use a SortedMap. You could use ConcurrentSkipListMap, which is thread-safe, or another SortedMap in combination with synchronizedSortedMap.
LinkedHashMap
有一个通过哈希表运行的双向链表。 FIFO 仅在写入(插入或删除)时改变链接。这使得版本的实现变得相当简单。#put()
/#putIfAbsent()
/#remove()
。在迭代时,不需要锁定,因为您可以安全地遵循“下一个”字段。只需在
#get()
上委托给 CHM 即可实现无锁读取。A
LinkedHashMap
has a doubly linked list running through a hashtable. A FIFO only mutates the links on a write (insertion or removal). This makes implementing a version fairly straightforward.#put()
/#putIfAbsent()
/#remove()
with a lock.On iteration, no lock is needed as you can safely follow the "next" field. Reads can be lock-free by just delegating to the CHM on a
#get()
.使用 <代码>Collections#synchronizedMap()。
这不是真的。您只需要同步任何视图(键集、值、条目集)上的迭代。另请参阅上面链接的 API 文档。
Use
Collections#synchronizedMap()
.This is not true. You only need to synchronize the iteration on any of the views (keyset, values, entryset). Also see the abovelinked API documentation.
到目前为止,我的项目使用 Apache Collections 中的 LRUMap,但它基于 SequencedHashMap。 Collections 提出 ListOrderedMap 但没有一个是线程-安全的。
我已切换到 MapMaker来自 Google Guava。您可以查看 CacheBuilder也。
Until now, my project used LRUMap from Apache Collections but it is based on SequencedHashMap. Collections proposes ListOrderedMap but none are thread-safe.
I have switched to MapMaker from Google Guava. You can look at CacheBuilder too.
嗯,简单的答案是使用您的
Comparator
运行的单调递增密钥提供程序。想想AtomicInteger
,每次插入时,都会创建一个用于比较的新键。如果您汇集真实密钥,则可以创建OrderedKey
的内部映射。这将消除对自定义比较器的需要,并为您提供一个很好的 O(1) 方法来计算大小(除非您允许删除,在这种情况下,也对这些进行计数,因此您只需从“中减去”所有成功删除”即可所有成功添加”,其中成功意味着实际创建或删除了条目)。
Um, simple answer would be to use a monotonically increasing key provider that your
Comparator
operates on. ThinkAtomicInteger
, and every time you insert, you create a new key to be used for comparisons. If you pool your real key, you can make an internal map ofOrderedKey<MyRealKeyType>
.This would obviate the need for a custom comparator, and give you a nice O(1) method to compute size (unless you allow removes, in which case, count those as well, so you can just subtract "all successful removes" from "all successful adds", where successful means an entry was actually created or removed).