Java并发和仅添加HashMaps

时间:2011-04-19 04:51:03

标签: java multithreading locking hashmap

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

将数据“放入”HashMap后,该数据永远不会更改。永远。每当改变这个数据结构的状态时,它实际上只是创建了一个新的“生成”结构,保留旧的结构。

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

4 个答案:

答案 0 :(得分:2)

不是真的。因为您可以写入它,所以当您这样做时,可能会触发基础数组的大小调整。如果你在另一个线程的读取过程中触发调整大小,你真的会弄乱它准确找到数据的能力!

答案 1 :(得分:1)

问题不在于hashmap中的数据,而是在插入内容时修改hashmap本身;它的结构。使用标准HashMap不能同时使用多个线程。

java并发包确实提供了一个线程安全的hashtmap:

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

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

答案 2 :(得分:1)

我知道你已经声明它不会被覆盖,但是值得考虑使用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

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

HTH

答案 3 :(得分:0)

您可以使用persistentMap代替HashMap,然后每个编写者都必须在添加新对象时将其锁定,并用新的对象替换对地图的引用,但读者总是可以从“当前”版本中读取(可能没有找到他们正在寻找的价值,因为它同时被添加。

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