ConcurrentHashMap和Collections.synchronizedMap(Map)的区别是什么?| Java Debug 笔记

286 阅读2分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接

ConcurrentHashMap和Collections.synchronizedMap(Map)的区别是什么?

我有一个会被多个线程同时修改的Map

在Java的API里面,有3种不同的实现了同步的Map实现

  • Hashtable
  • Collections.synchronizedMap(Map)
  • ConcurrentHashMap

据我所知,HashTable 已经是一个很老的实现了(扩展了已经过时的字典类)。后来为了适配Map接口进行了调整,它存在着严重的伸缩性问题,已经不鼓励在新项目里面使用了

但是关于其他的两个呢?ConcurrentHashMap和Collections.synchronizedMap(Map)的区别是什么?分别适合什么场景呢?

回答一

╔═══════════════╦═══════════════════╦═══════════════════╦═════════════════════╗
║   Property    ║     HashMap       ║    Hashtable      ║  ConcurrentHashMap  ║
╠═══════════════╬═══════════════════╬═══════════════════╩═════════════════════╣ 
║      Null     ║     allowed       ║              not allowed                ║
║  values/keys  ║                   ║                                         ║
╠═══════════════╬═══════════════════╬═════════════════════════════════════════╣
║ Thread-safety ║                   ║                                         ║
║   features    ║       no          ║                  yes                    ║
╠═══════════════╬═══════════════════╬═══════════════════╦═════════════════════╣
║     Lock      ║       not         ║ locks the whole   ║ locks the portion   ║        
║  mechanism    ║    applicable     ║       map         ║                     ║ 
╠═══════════════╬═══════════════════╩═══════════════════╬═════════════════════╣
║   Iterator    ║               fail-fast               ║ weakly consistent   ║ 
╚═══════════════╩═══════════════════════════════════════╩═════════════════════╝

关于锁的机制,HashTable锁一个对象, ConcurrentHashMap只锁一个桶

回答二

按照你的需求,使用ConcurrentHashMap吧。它允许Map被多个线程并发修改并且是非阻塞的。 Collections.synchronizedMap(map) 创建的是一个阻塞的Map,会降低性能的,尽管可以保持一致性(使用正确的话)

用第二个选择的话,你就需要保证数据的一致性,每一个线程都需要有一个map的最新的视图。如果性能是至关重要的话,那就用第一种,每个线程只能插入数据到map,并且读取的频率会更低。

回答三

ConcurrentHashMap是更好的,如果你可以使用到的话,因为它至少需要Java5版本

它设计的初衷就是多线程情况下的高伸缩性。当只有一个线程使用的话,性能不会太好的,但是多线程使用这个map的时候就好得多了。

我找到一个博客复制了一个表格,来自一本我很推荐的名叫Java Concurrency In Practice的优秀书籍

Collections.synchronizedMap只有在你需要用其他特性去包装一个map的时候,它才有意义,例如一些排序的map,像treemap那种。

文章翻译自Stack Overflow:stackoverflow.com/questions/5…