Java 并发和 Add-Only HashMap

发布于 2024-11-01 21:19:11 字数 257 浏览 1 评论 0原文

我正在编写一个广泛使用大型 HashMap 的程序。它是多线程的,所以我在访问它时使用了读写锁。然而,它有一个我想利用的特殊属性。

将数据“放入”HashMap 后,该数据永远不会更改。曾经。每当对此数据结构的状态进行更改时,它实际上只是创建新“一代”的结构,而使旧的结构保持不变。

也就是说,在知道另一个线程永远不会写入您正在读取的值的情况下,在另一个线程写入值的同时从 HashMap 读取值是否安全?是否有一些简单的哈希表结构可以给我这种保证?

I'm writing a program that makes extensive use of large HashMaps. It is multithreaded, so I've used read-write locks when accessing it. However, it has a special property that I'd like to exploit.

After data is "put" into the HashMap, that data is never changed. Ever. Whenever a change to the state of this data structure is made, it actually just creates a new "generation" of the structure, leaving the old one intact.

That is, is it safe to read a value from a HashMap at the same time that another thread is writing a value, knowing that the other thread will never be writing to the value you're reading? Is there some simple hashtable structure that will give me this sort of guarantee?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心奴独伤 2024-11-08 21:19:11

并不真地。因为您可以对其进行写入,所以当您这样做时可能会触发底层数组的大小调整。如果您在另一个线程读取过程中触发调整大小,那么您真的会破坏它准确查找数据的能力!

Not really. Because you can write to it, you may trigger a resize of the underlying array when you do. If you trigger a resize in the middle of another thread's read, you're really going to mess with its ability to find the data accurately!

温折酒 2024-11-08 21:19:11

问题不在于哈希映射中的数据,而是当您插入某些内容时正在修改哈希映射本身;它的结构。您无法使用标准 HashMap 同时使用多个线程来做到这一点。

java并发包确实提供了线程安全的哈希图:

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html

在内部,这将使用线程安全的非锁定方法。

The problem isn't the data IN the hashmap, it's that you're modifying the hashmap itself when you insert something; its structure. You can't do that with multiple threads at once with a standard HashMap.

The java concurrent package does offer a thread-safe hashtmap:

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html

Internally this is going to be using non-locking methods of thread safety.

还不是爱你 2024-11-08 21:19:11

我知道您已经声明它不会被覆盖,但值得考虑 ConcurrentHashMap,即使只是因为您不再需要“锁定”代码。

这个特殊的映射(自 java 1.5 起)保证您永远不会遇到 ConcurrentModificationException,因为它会返回最后一个“完整”写入。

http://download.oracle.com /javase/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html

对于多个并发读取来说它也非常快。请参阅这篇文章以获取更多信息:

http:// www.ibm.com/developerworks/java/library/j-jtp07233/index.html#N101CD

其他需要注意的事项:它不允许空键/值,并且它还有另一个方便的方法 putIfAbsent。

华泰

I know you've stated that it won't be overwritten, but it's worth considering a ConcurrentHashMap, if only because you won't need your 'locking' code any more.

This special map (since java 1.5) guarantees that you'll never get a ConcurrentModificationException, because it'll return you the last 'complete' write.

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html

It's also super-fast for multiple concurrent reads. See this article for a bit more info:

http://www.ibm.com/developerworks/java/library/j-jtp07233/index.html#N101CD

Other things to note: it doesnt allow null keys/values, and it has another handy method, putIfAbsent.

HTH

a√萤火虫的光℡ 2024-11-08 21:19:11

您可以使用持久映射来代替 HashMap,然后每个写入者在添加新对象并用新对象替换对映射的引用时都必须锁定它,但读者始终可以从“当前”版本中读取(可能找不到)他们正在寻找的值,因为它是同时添加的,

请注意,读取和写入对 Map 的引用必须以原子方式完成。

Instead of the HashMap you could use a persistentMap, then each writer will have to lock it while adding the new object and replacing the reference to the map with the new one, but readers could always read from the "current" version (possibly not finding the value they are looking for, because it is concurrently added.

Note that reading and writing the reference to the Map has to be done atomically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文