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

我有一个地图,该地图将同时被多个线程修改。 java

Java API中彷佛有三种不一样的同步Map实现: 安全

  • Hashtable
  • Collections.synchronizedMap(Map)
  • ConcurrentHashMap

据我了解, Hashtable是一个旧的实现(扩展了过期的Dictionary类),后来对其进行了调整以适合Map接口。 虽然它同步的,但彷佛存在严重的可伸缩性问题 ,所以不建议用于新项目。 并发

可是其余两个呢? Collections.synchronizedMap(Map)ConcurrentHashMap返回的Collections.synchronizedMap(Map)之间有什么区别? 哪种适合哪一种状况? app


#1楼

ConcurrentHashMap ,该锁将应用于段而不是整个Map。 每一个段都管理本身的内部哈希表。 该锁仅适用于更新操做。 Collections.synchronizedMap(Map)同步整个地图。 ide


#2楼

  1. 若是数据一致性很是重要-请使用Hashtable或Collections.synchronizedMap(Map)。
  2. 若是速度/性能很是重要,而且数据更新可能会受到影响,请使用ConcurrentHashMap。

#3楼

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

关于锁定机制: Hashtable 锁定对象 ,而ConcurrentHashMap 锁定bucket性能


#4楼

二者之间的主要区别在于ConcurrentHashMap将仅锁定正在更新的数据部分,而其余线程能够访问其余部分数据。 可是, Collections.synchronizedMap()将在更新时锁定全部数据,其余线程仅在释放锁定后才能访问数据。 若是更新操做不少而读取操做相对较少,则应选择ConcurrentHashMapspa

另一个区别是ConcurrentHashMap不会保留传入的Map中元素的顺序。它在存储数据时相似于HashMap 。 不能保证保留元素顺序。 虽然Collections.synchronizedMap()将保留在经过Map的元素顺序。例如,若是你传递一个TreeMapConcurrentHashMap ,这些元素才能在ConcurrentHashMap可能不同,在顺序TreeMap ,但Collections.synchronizedMap()将保留顺序。 .net

此外, ConcurrentHashMap能够保证在一个线程更新映射而另外一个线程遍历从映射得到的迭代器时,不会引起ConcurrentModificationException 。 可是,对此不保证Collections.synchronizedMap()线程

一篇文章展现了这二者的区别以及ConcurrentSkipListMapcode


#5楼

并发哈希图

  • 当项目中须要很高的并发时,应使用ConcurrentHashMap。
  • 它是线程安全的,无需同步整个映射。
  • 用锁完成写操做时,读操做可能会很是快。
  • 在对象级别没有锁定。
  • 在哈希图存储桶级别,锁定的粒度要精细得多。
  • 若是一个线程尝试修改它,而另外一个线程对其进行迭代,则ConcurrentHashMap不会引起ConcurrentModificationException。
  • ConcurrentHashMap使用多个锁。

SynchronizedHashMap

  • 对象级别的同步。
  • 每一个读/写操做都须要获取锁定。
  • 锁定整个集合是性能开销。
  • 本质上,这仅容许访问整个地图的一个线程,并阻止全部其余线程。
  • 它可能引发争用。
  • SynchronizedHashMap返回Iterator,并发修改后快速失败。

资源

相关文章
相关标签/搜索