ConcurrentHashMap与同步的HashMap相比有何优势?

181

使用包装类SynchronizedMapHashMapConcurrentHashMap上有何区别?仅仅是能否在迭代过程中修改HashMapConcurrentHashMap)吗?

13个回答

166

同步的 HashMap

  1. 每个方法都使用 对象级锁 进行同步。因此,在synchMap上执行get和put方法时会获取锁。

  2. 锁定整个集合会导致性能开销。当一个线程持有锁时,其他线程无法使用该集合。

ConcurrentHashMap 在JDK 5中引入。

  1. 没有对象级别上的锁定,锁定的粒度更细。对于 ConcurrentHashMap,锁可能在 哈希映射桶级别 上。

  2. 低级别锁定的效果是可以同时进行读取和写入,并发读写对于同步集合来说不可能。这使得其具有更高的可扩展性。

  3. 如果一个线程在迭代 ConcurrentHashMap 时另一个线程试图修改它,它不会抛出 ConcurrentModificationException

这篇文章 Java 7: HashMap vs ConcurrentHashMap 是一篇非常好的阅读材料。强烈推荐。


8
HashtableSynchronized HashMap 有什么不同? - roottraveller
1
在ConcurrentHashMap和Synchronized HashMap之间,你会推荐哪一个? - Blunderchips
5
值得一提的是,ConcurrentHashMapsize() 方法返回的结果可能已经过时。根据《Java并发编程实践》一书,size() 方法允许返回一个近似值而不是准确的计数。因此,应该谨慎使用这个方法。 - Andrii Lisun
1
@roottraveller 关于Hashtable和Synchronized HashMap的区别,请参考以下链接:https://dev59.com/9mox5IYBdhLWcg3w8ItJ - Narendra Jaggi

90

简短回答:

这两个地图都是实现了Map接口的线程安全的实现。在需要高并发的情况下,ConcurrentHashMap 的实现可以提供更高的吞吐量。

Brian Goetz关于ConcurrentHashMap背后的思想的文章是非常好的阅读材料。强烈推荐。


1
这是什么?HashMap:请注意,此实现未同步,以防止意外的非同步访问地图:Map m = Collections.synchronizedMap(new HashMap(...));http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html - X-HuMan
6
"Brian Goetz的文章…非常值得一读。" - 而更加值得一提的是他的"Java并发实践"一书。 - Alex Fedulov
文章的链接已经失效。 - Walter Tross

36

ConcurrentHashMap是线程安全的,而不需要同步整个映射。读取操作非常快速,而写操作则使用锁进行。


33

我们可以通过使用ConcurrentHashMap和synchronizedHashmap来实现线程安全。但是,如果您查看它们的架构,差异很大。

  1. synchronizedHashmap

它将在对象级别维护锁定。因此,如果您要执行任何操作(如put/get),则必须首先获取锁定。同时,不允许其他线程执行任何操作。因此,在同一时间内,只有一个线程可以对其进行操作。因此等待时间会增加。我们可以说,与ConcurrentHashMap相比,性能较低。

  1. ConcurrentHashMap

它将在段级别维护锁定。默认情况下,它有16个段并维护并发级别为16。因此,同时,16个线程可以在ConcurrentHashMap上进行操作。此外,读取操作不需要锁定。因此,任意数量的线程可以对其执行get操作。

如果thread1想在段2中执行put操作,而thread2想在段4中执行put操作,则允许在此处执行。这意味着,16个线程可以同时对ConcurrentHashMap执行更新(put/delete)操作。

因此,这里的等待时间会更少。因此,性能比synchronizedHashmap相对更好。


非常好的解释 非常感谢 - amoljdv06

13

SynchronizedMapConcurrentHashMap 都是线程安全的类,可以在多线程应用程序中使用,它们之间的主要区别在于它们如何实现线程安全。

SynchronizedMap 在整个 Map 实例上获取锁,而 ConcurrentHashMap 将 Map 实例分成多个段,并对其进行锁定。

enter image description here

enter image description here


1
这些段在ConcurrentHashMap中是什么? - stinger

11

两者都是HashMap的同步版本,其核心功能和内部结构有所不同。

ConcurrentHashMap由内部段组成,可以概念化为独立的HashMap。在高并发执行中,所有这些段都可以由单独的线程锁定。因此,多个线程可以从ConcurrentHashMap获取/放置键值对,而无需阻止/等待彼此。这是为了更高的吞吐量。

Collections.synchronizedMap(),我们获得了一个同步版本的HashMap,并以阻塞方式访问它。这意味着如果多个线程尝试同时访问synchronizedMap,则它们将被允许以同步方式依次获取/放置键值对。


7

ConcurrentHashMap使用更细粒度的锁机制,称为锁分离,以允许更大程度的共享访问。因此,它提供了更好的并发性可伸缩性

此外,ConcurrentHashMap返回的迭代器是弱一致性的,而不是Synchronized HashMap使用的快速失败技术


3

SynchronizedMap 上的方法持有对象上的锁,而在 ConcurrentHashMap 中存在“锁分离”概念,其中锁定内容的桶。因此,ConcurrentHashMap 具有更好的可扩展性和性能。


2

ConcurrentHashMap :

1) 两个映射都是Map接口的线程安全实现。

2) ConcurrentHashMap 用于在期望高并发的情况下提供更高的吞吐量。

3) 对象级别没有锁定。

Synchronized Hash Map:

1) 每个方法都使用对象级别锁定进行同步。


1

一个简单的ConcurrentHashMap和Synchronized HashMap性能测试。测试流程是在一个线程中调用put,并在三个线程上同时调用get。正如@trshiv所说,当读取操作无需锁定时,ConcurrentHashMap具有更高的吞吐量和速度。结果是当操作次数超过10^7时,ConcurrentHashMap比Synchronized HashMap快2x


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接