多线程下使用哈希表

目录

1.HashTable

(1)基本概念

(2) 使用背景

2.ConcurrentHashMap

(1)基本概念

(2)核心设计目标

(3) 设计原理

3.ConcurrentHashMap和HashTable的对比表


HashMap本身是不安全的,所以要在多线程下使用哈希表,我们可以使用:

• Hashtable

• ConcurrentHashMap

1.HashTable

(1)基本概念

Hashtable 是 Java 早期提供的线程安全哈希表实现(java.util.Hashtable),通过 全局锁(synchronized) 保证线程安全。

简单来说,HashTable就是简单地把方法加上了synchronized关键字。这等于是直接对HashTable对象本身加锁。

但是HashTable的性能较低:

• 如果多线程访问同⼀个Hashtable就会直接造成锁冲突。

• size属性也是通过synchronized来控制同步,也是⽐较慢的。

• ⼀旦触发扩容,就由该线程完成整个扩容过程.这个过程会涉及到⼤量的元素拷⻉,效率会⾮常低。

(2) 使用背景

由于HashTable直接对整个哈希表加锁,虽然保证了线程安全问题,但是也让HashTable的效率极低:

当任意两个线程同时访问哈希表上的任意数据时就会触发锁竞争。但是,如果两个线程分别访问哈希表上的不同链表时,不会触发线程安全问题,但是HashTable却不允许这种情况发生。

 Hashtable 是 Java 早期线程安全哈希表的实现,通过 全局锁 保证线程安全,但其粗粒度锁机制导致高并发场景下性能低下,已被 ConcurrentHashMap 取代。

现代开发中应避免使用 Hashtable,除非维护遗留代码或处理极低并发的简单需求。理解其设计缺陷(如锁竞争、扩容阻塞)有助于更好地选择高性能并发容器(如 ConcurrentHashMap)。

2.ConcurrentHashMap

(1)基本概念

ConcurrentHashMap 是 Java 中用于高并发场景的线程安全哈希表实现,属于 java.util.concurrent 包。它在多线程环境下提供了高效的并发读写能力,同时避免了传统同步容器(如 Hashtable 或 Collections.synchronizedMap)的性能瓶颈。

(2)核心设计目标

  • 线程安全:支持多线程并发读写,无需外部同步。

  • 高吞吐量:通过细粒度锁或无锁操作(CAS)减少竞争。

  • 弱一致性迭代器:迭代过程中允许其他线程修改数据,不会抛出 ConcurrentModificationException

  • 可扩展性:在数据量增大时,性能不会显著下降。

(3) 设计原理

在 Java 8 之前,ConcurrentHashMap 使用 分段锁(Segment) 机制(类似于分桶锁)。分段锁是将所有链表分成一段一段的,针对每一段进行加锁,相比于对整个哈希表加锁来说提高了效率。
 

Java 8 及以后 改为基于 CAS(Compare-And-Swap) 和 synchronized 锁 的优化设计,核心改进如下:

1)读写操作

  • 写操作

    • 插入(put)、删除(remove)等写操作仅锁定当前桶的头节点(锁桶)

    • 若桶结构为红黑树,则锁定树的根节点。

  • 读操作
    无锁(基于 volatile 变量和内存可见性),支持高并发读。

2)原子性

提供了一系列原子操作,充分利用了CAS:

  • putIfAbsent(key, value):仅当键不存在时插入。

  • replace(key, oldValue, newValue):条件替换。

  • compute(key, remappingFunction):原子计算新值。

3)扩容机制

  • 多线程协同扩容
    当表需要扩容时,其他线程可以协助完成数据迁移,避免单线程阻塞。

  • 扩容期间读写兼容
    读操作无需加锁,可直接访问旧表或新表;写操作若遇到迁移中的桶,会协助迁移。迁移期间新表和旧表同时存在,知道扩容完毕,删除旧表。

  • 插入和查找:
    在此期间,插入只往新表中插入;查找需要在新表和旧表中同时查找。

3.ConcurrentHashMap和HashTable的对比表

场景Hashtable / synchronizedMapConcurrentHashMap
读操作全局锁,串行化无锁,完全并发
写操作全局锁,串行化桶级锁,多线程可并行写入不同桶
扩容单线程扩容,阻塞所有操作多线程协同扩容,读写不阻塞
内存一致性强一致性弱一致性(更高吞吐量)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值