Java ConcurrentHashMap优于HashMap性能吗?

我刚刚阅读了“清洁代码”一书,并发现了这一说法:

当Java年轻的时候,Doug Lea写了一本开创性的书[8] Java中的Concurrent Programming。 随着本书的出现,他开发了几个线程安全的集合,后来成为java.util.concurrent包中JDK的一部分。 该软件包中的集合对于multithreading情况是安全的,并且它们表现良好。 实际上,几乎所有情况下ConcurrentHashMap实现都比HashMap表现更好 。 它还允许同时并发读取和写入,并且它具有支持常见复合操作的方法,否则这些操作不是线程安全的。 如果Java 5是部署环境,请从ConcurrentHashMap开始

请注意,在上面的引用中,我使用了“[n]”,其中n是某个数字,表示作者提供引用的地方,正如您所看到的,他没有为粗体部分提供任何参考。

并不是说我不相信这个陈述,但我很想知道这个陈述的支持证据。 那么,有没有人知道任何显示ConcurrentHashMapHashMap的性能统计信息的资源? 或者任何人都可以向我解释为什么ConcurrentHashMap比HashMap快?

当我rest时,我可能会调查ConcurrentHashMap的工作实现,但是现在我想听听SOERS的回答。

Doug Lea非常擅长这些东西,所以如果有一次他的ConcurrentyHashMap比Joshua Bloch的HashMap表现得更好,我也不会感到惊讶。 但是从Java 7开始,H​​ashMap的第一个@author也成了Doug Lea。 显然现在HashMap没有理由比它的同伴堂兄慢。

出于好奇,我还是做了一些基准测试。 我在Java 7下运行它。条目越多,性能越接近。 最终,ConcurrentHashMap占HashMap的3%,非常值得注意。 瓶颈实际上是内存访问,俗话说“内存是新磁盘(磁盘是新磁带)”。 如果条目在缓存中,则两者都会很快; 如果条目不适合缓存,则两者都会很慢。 在实际应用程序中,映射不一定要与其他人竞争驻留在缓存中。 如果经常使用地图,它会被缓存; 如果没有,它不会被缓存,这是真正的决定因素,而不是实现(两者都由同一专家实现)

 public static void main(String[] args) { for(int i=0; i<100; i++) { System.out.println(); int entries = i*100*1000; long t0=test( entries, new FakeMap() ); long t1=test( entries, new HashMap() ); long t2=test( entries, new ConcurrentHashMap() ); long diff = (t2-t1)*100/(t1-t0); System.out.printf("entries=%,d time diff= %d%% %n", entries, diff); } } static long test(int ENTRIES, Map map) { long SEED = 0; Random random = new Random(SEED); int RW_RATIO = 10; long t0 = System.nanoTime(); for(int i=0; i 

如果您只使用单个线程访问HashMap,HashMap最快(它不执行任何同步),如果您从多个线程访问它,ConcurrentHashMap比手动粗粒度同步更快。 请看这里进行一些比较:

http://www.codercorp.com/blog/java/why-concurrenthashmap-is-better-than-hashtable-and-just-as-good-hashmap.html

HashMap可能较慢的原因是因为它必须检测ConcurrentModification以知道何时抛出exception。 ConcurrentHashMap不必检查modCount以知道何时抛出(但它确实将它用于size()和isEmpty())。 获取锁是非常快的,特别是在单线程情况下,当你已经持有锁时,但是检查modCount是两次读取和跳转 – 如果不相等HashMap必须支付以抛出CoModException。

我建议您阅读集合类的源代码,这样您就可以知道在进行方法调用时他们正在做多少工作。 在只有字典获取/放置的完全私有映射的情况下,您通常可以使用剥离的HashMap而不使用任何modCount或甚至大小跟踪来提高性能。

这是一种很难以某种方式certificate的橡皮语。 你如何在“几乎所有情况”中测量某些东西?

ConcurrentHashMap可能比同步的HashMap更好。 争论越多,差异就越显着。 另一方面,未同步的HashMap可能比ConcurrentHashMap更快,因为在后一种情况下不必要的锁定开销。


我也希望看到该陈述的背景,以及该书作者提出的支持它的证据。 并且有关未使用的假设的证据表明, “几乎所有”用于哈希映射的用例都涉及同步。