多线程进阶2 - 哈希表

前言

HashMap 本身不是线程安全的,在多线程环境下使用哈希表可以使用:

  • 1)Hashtable
  • 2)  ConcurrentHashMap

一,Hashtable

Hashtable 只是简单的将 HashMap 中比较关键的方法加上了 synchronized ,也就是使用了 synchronized 能对方法加锁这一特点(实际上是对 Hashtable 对象加锁),但是这样加锁会出现以下三个缺点:

  1. 如果多个线程同时访问同一个 Hashtable 对象,就会直接出现锁冲突。而实际上因为 HashMap 是使用链表的方式的方式来解决哈希冲突的,所以当多个线程操作不同的链表时,是不可能出现线程安全问题的,用上述方式加锁就会大大降低效率。
  2. size 属性也是通过 synchronized 来控制同步,也会降低效率
  3. 一旦触发扩容,就由该线程完成整个扩容过程,这个过程会涉及到大量的元素拷贝, 效率会非常低。

所以我们一般使用另一个哈希表 —— ConcurrentHashMap

二,ConcurrentHashMap

与 Hashtable 相比,ConcurrentHashMap 所作的改进:

1) ConcurrentHashMap 将一个针对对象的大锁,改进成了针对每一个链表单独的小锁(就是将每个链表的头节点作为锁对象),大幅度降低了锁冲突的概率。(最核心)

2) ConcurrentHashMap 充分利用了 CAS 的特性,省略了一些不必要的加锁操作,比如统计 hash 表中的元素个数,这时候就可以使用原子操作(CAS)来修改元素个数。

3)ConcurrentHashMap 对读取操作没有加锁,也就是说读与读,读与写之间,都不会发生所冲突,但是这样可能会出现 "读到一个修改到一半的数据" ,针对这种情况,ConcurrentHashMap在底层代码实现的时候,增加了亿点点细节,比如修改数据的时候,会避免使用一些非原子的操作,也就是说,我们读取的数据要么是修改之前的值,要么是修改之后的值,不会出现"读到一半的情况"。

4)ConcurrentHashMap 针对扩容操作,做出了单独的优化,当出现扩容的时候,他不是一次操作将所有数据拷贝完成,而是分成多次,每次只拷贝一部分数据,从而避免单次操作过于卡顿。

ConcurrentHashMap 方法的使用与 HashMap 几乎一样,这里不过多赘述。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶祇秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值