首页 > 编程语言 >从源码解读为什么使用ConcurrentHashMap,而不使用Hashtable与HashMap

从源码解读为什么使用ConcurrentHashMap,而不使用Hashtable与HashMap

时间:2024-10-29 09:49:33浏览次数:8  
标签:ConcurrentHashMap HashMap 并发 源码 线程 Hashtable putVal put

目录

1 问题

2 答案

2.1 锁机制不同:ConcurrentHashMap 提升并发性能

2.2 迭代的安全性

2.3更好的扩展性

3 带着答案理解源码

3.1 HashMap的putVal()方法:

3.2 HashTable的put()方法

3.3  ConcurrentHashMap的putVal()方法

4 总结 


1 问题

我们都知道Hashmap 线程不安全,而Hashtable线程安全,但Hashtable 用的不多,更推荐ConcurrentHashMap ,为什么?

2 答案

ConcurrentHashMap 是相较于 Hashtable 更推荐的线程安全 Map 实现,原因主要在于它在性能线程安全方面都进行了优化,特别适合高并发环境中使用。下面是几方面的比较:

2.1 锁机制不同:ConcurrentHashMap 提升并发性能

Hashtable采用 synchronized 关键字对整个 Map 进行同步操作,所有线程必须争夺一个锁来访问或修改 Hashtable,在高并发场景下容易产生大量锁争用,导致效率低下。

ConcurrentHashMap采用了 分段锁(Segmented Locking),将数据划分成多个小段,每段有自己独立的锁。这样不同线程可以同时访问不同段的数据,大幅提高并发度。JDK 8 以后,ConcurrentHashMap 进一步优化为使用 CAS(Compare-And-Swap)+ 自旋锁 的方式,提高了性能和并发性。

2.2 迭代的安全性

Hashtable:直接使用 synchronized 锁定整个表,因此在遍历时无法保证实时更新的安全性(可能导致 ConcurrentModificationException)。

ConcurrentHashMap:采用 弱一致性迭代(弱一致性迭代器),即允许在迭代过程中进行更新操作,而不会抛出异常。迭代器能够在遍历的同时处理并发更新,确保更高的吞吐量。

2.3更好的扩展性

• ConcurrentHashMap 在高并发环境下依然能够保持高效的读写操作,而 Hashtable 在高并发场景中,随着线程数增加,其性能会显著下降。对于大规模、多线程环境下的数据存储和读取,ConcurrentHashMap 是首选。

3 带着答案理解源码

三者的区别在于是否线程安全,线程安全情况下的效率问题。接下来针对三者的put() 方法源码帮助理解:

3.1 HashMap的putVal()方法:

HashMap是执行的put()方法 然后调用的putVal()方法,如下图所示,代码中没有任何加锁的操作,因此在高并发的场景下会出现问题,因此不使用。

3.2 HashTable的put()方法

HashTable则是put() 方法 :由代码我们可以轻易看出,HashTable是直接在put方法前加上了synchronized 关键字,这意味着每次调用 put 方法时都会锁住整个 Hashtable 对象,即对 put 操作持有该对象锁。这种设计使得 Hashtable 是线程安全的,但也会导致在高并发场景下性能下降,因为一次只能有一个线程执行 put 操作,其他线程会被阻塞等待。

3.3  ConcurrentHashMap的putVal()方法

ConcurrentHashMap是执行的put()方法 然后调用的putVal()方法,因为代码过长,此处只展示关键代码,f 为插入数据的所在节点这里使用的则是获取该节点的对象锁,而不是对整个表加锁,并且 if (tabAt(tab, i) == f) 进行CAS操作,保证了在高并发环境中的线程安全和性能优化。因此相比于其他两者更推荐使用ConcurrentHashMap。

4 总结 

1. HashMap 线程不安全。

2. HashTable 线程安全,但设计不好,对整个表加锁,导致性能下降,效率低。

3. ConcurrentHashMap 线程安全,设计也较好,只会获得执行操作节点的对象锁,对该节点加锁,同时通过CAS操作,保证性能和并发性。

ConcurrentHashMap 在并发处理上具有显著的性能优势和较低的锁争用情况,因此在 Java 开发中,ConcurrentHashMap 已逐渐取代了 Hashtable,成为更好的线程安全 Map 解决方案。

标签:ConcurrentHashMap,HashMap,并发,源码,线程,Hashtable,putVal,put
From: https://blog.csdn.net/weixin_49418695/article/details/143319976

相关文章