Java基础(7)-ConcurrentHashMap与CAS

本文详细解析了JDK5和JDK8中ConcurrentHashMap的实现原理,包括分段锁和CAS技术的应用,以及ABA问题的解决方案。探讨了在高并发环境下,ConcurrentHashMap如何通过细分锁的数据规模和使用CAS技术提升性能。

ConcurrentHashMap是J.U.C包下一个十分重要的并发容器之一,它和Hashtable一样是并发安全的,但是它的性能却比Hashtable好很多,且由于在高并发环境下,使用HashMap的put方法时会造成堵塞,这将会消耗许多的CPU时间片,造成不必要的等待,所以在并发情况下应当使用ConcurrentHashMap替代HashMap

1.1 JDK 5中ConcurrentHashMap的实现原理

早期的ConcurrenntHashMap通过分段锁Segment和HashEntry细化了锁的范围,实现了并发安全,由于不像Hashtable一样使用全局锁, 而是细分锁的数据规模,所以性能上比同步的Hashtable高了许多,详细了解可以阅读这篇文章:
https://www.cnblogs.com/ITtangtang/p/3948786.html

在这里插入图片描述

1.2 JDK 8中ConcurrentHashMap的实现原理

原理:使用CAS技术与同步锁技术相结合

1.不允许插入null键或null值
2.putAll源码中,不直接使用Java层次级别的数组更新,而是使用CAS的方式直接从系统底层内存空间中更新,所以并发安全

	final V putVal(K key, V value, boolean onlyIfAbsent) {
        if (key == null || value == null) throw new NullPointerException();
        int hash = spread(key.hashCode());
        int binCount = 0;
        for (Node<K,V>[] tab = table;;) {
            Node<K,V> f; int n, i, fh;
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
            //通过cas进行添加
                if (casTabAt(tab, i, null,
                             new Node<K,V>(hash, key, value, null)))
                    break;                    
            }
            //....

1.3 CAS基本原理

CAS 全称是 compare and swap,即比较和交换,是一种用于在多线程环境下实现同步功能的机制。CAS 操作包含三个操作数: 内存位置预期数值和新值。CAS 的实现逻辑是将内存位置处的数值与预期数值相比较,若相等,则说明没有其他线程对其进行过修改,将内存位置处的值替换为新值。若不相等,则说明有其他线程对其进行了修改,不做任何操作,即原地自旋等待

在 Java 中,Java 并没有直接实现 CAS,CAS 相关的实现是通过 C++ 内联汇编的形式实现的。Java 代码需通过 JNI 才能调用。

像synchronized这种独占锁属于悲观锁,它是在假设一定会发生冲突的,那么加锁恰好有用,除此之外,还有乐观锁,乐观锁的含义就是假设没有发生冲突,那么我正好可以进行某项操作,如果要是发生冲突呢,那就重试直到成功,乐观锁最常见的就是CAS。

1.4 ABA问题

CAS 由三个步骤组成,分别是“读取->比较->写回”。考虑这样一种情况,线程1和线程2同时执行 CAS 逻辑,两个线程的执行顺序如下:

时刻1:线程1执行读取操作,获取原值 A,然后线程被切换走
时刻2:线程2执行完成 CAS 操作将原值由 A 修改为 B
时刻3:线程2再次执行 CAS 操作,并将原值由 B 修改为 A
时刻4:线程1恢复运行,将比较值与原值进行比较,发现两个值相等。然后用新值写入内存中,完成 CAS 操作
如上流程,线程1并不知道原值已经被修改过了,在它看来并没什么变化,所以它会继续往下执行流程。

对于 ABA 问题,通常的处理措施是对每一次 CAS 操作设置版本号。J.U.C包下提供了一个可处理 ABA 问题的原子类 AtomicStampedReferenc,具体可以查阅资料了解

ConcurrentHashMap和CAS就先简单地了解到这里吧…查阅其他资料看到的都是cpp和汇编的解读,看得一头雾水,我太难了,就先这样吧(゜-゜)つロ (干杯)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BoringRong

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

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

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

打赏作者

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

抵扣说明:

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

余额充值