ConcurrentHashMap

⭐ 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:JavaEE
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖


在这里插入图片描述

1. Hashtable

Hashtable保证线程安全,主要就是给关键方法加上synchronized,相当于直接针对Hashtable 对象本⾝加锁。
例如:

public synchronized Type put(Type key,Type value){}
public synchronized Type get(Type key,Type value){}
  • 如果多线程访问同⼀个 Hashtable 就会直接造成锁冲突
  • size 属性也是通过 synchronized 来控制同步,也是⽐较慢的
  • ⼀旦触发扩容,就由该线程完成整个扩容过程。这个过程会涉及到⼤量的元素拷贝,效率会⾮常低
    在这里插入图片描述

2. ConcurrentHashMap

  1. ConcurrentHashMap最核心的改进就是把一个全局的大锁,改成了每个链表独立的一把小锁。就是把每个链表的头结点作为锁对象(synchronized可以使用任意对象作为锁对象)。大幅度降低了锁冲突的概率。
    在这里插入图片描述
  2. 充分利用CAS特性,把一些不必要加锁的环节省略加锁。
    比如:size属性就通过CAS来更新,避免出现重量级锁的情况。
  3. 读操作没有加锁(但是使⽤了 volatile 保证从内存读取结果),只对写操作进⾏加锁。加锁的⽅式仍然是是⽤ synchronized,但是不是锁整个对象,⽽是 “锁桶” (⽤每个链表的头结点作为锁对象),⼤⼤降低了锁冲突的概率。
    使得读和读、读和写之间都不会有锁竞争。

ConcurrentHashMap的底层编码,在修改的时候会避免使用++ --这种非原子的操作。而使用 = 进行修改(原子的)。
读的时候,要么读到的是写之前的旧值,要么是读到写之后的新值,不会出现读到一个一半的值。

  1. 优化了扩容⽅式: 化整为零,多次搬运
    发现需要扩容的线程,只需要创建⼀个新的数组,同时只搬⼏个元素过去。
    扩容期间,新⽼数组同时存在。后续每个来操作 ConcurrentHashMap 的线程,都会参与搬家的过程,每个操作负责搬运⼀⼩部分元素。搬完最后⼀个元素再把⽼数组删掉。
    这个期间,插⼊只往新数组加。但查找需要同时查新数组和⽼数组

Hashtable和HashMap都实现了Map接口,但是Hashtable的实现是基于Dictionary抽象类的。ConcurrentHashMap是HashTable的替代,比HashTable的扩展性更好。

  • 24
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值