一、前景回顾
今天分享下java并发包下的CAS相关的原子操作,以及Java 8如何改进和优化CAS操作的性能。Atomic系列的原子类,高频出现在并发编程、JDK源码、各种开源项目中。
二、场景引入
假设多个线程需要对一个变量不停的累加1,比如说下面这段代码:
package com.alipay.rcopcenter.web;
/**
* @author rongzhi.xzp
* @version $Id: HelloWorld.java, v 0.1 2021年10月13日 3:54 PM rongzhi.xzp Exp $
*/
public class HelloWorld {
private int data = 0;
//多线程并发 data++
}
实际上,上面那段代码是不ok的,因为多个线程直接这样并发的对一个data变量进行修改,是线程不安全性的行为,会导致data值的变化不遵照预期的值来改变。
举个例子,比如说20个线程分别对data执行一次data++操作,我们以为最后data的值会变成20,其实不是,最后可能data的值是18,或者是19,都有可能,因为多线程并发操作下,就是会有这种安全问题,导致数据结果不准确。
三、解决方案
对于这种简单的data++类的操作,可以换一种做法,java并发包下面提供了一系列的Atomic原子类,比如说AtomicInteger。
import java.util.concurrent.atomic.AtomicInteger;
public class HelloWorld {
private static AtomicInteger data = new AtomicInteger(0);
//多线程并发执行 data.incrementAndGet()
}
多个线程可以并发的执行AtomicInteger的incrementAndGet()方法,意思是把data的值累加1,接着返回累加后最新的值,这个代码里就没有加锁和释放锁的操作了,实际上,Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。
什么是CAS呢?他的全称是:Compare and Set,先比较再设置的意思。
假如说有3个线程并发的要修改一个AtomicInteger的值,他们底层的机制如下:首先,每个线程都会先获取当前的值,接着走一个原子的CAS操作,原子的意思是这个CAS操作一定是完整执行完,不会被别的线程打断,然后CAS操作里,会比较一下当前值和上次获取的值是否一致,如果一致说明没其他线程改过这个值,那当前线程可以累积加1,同理,如果有线程在执行CAS的时候,发现自己之前获取的值跟当前的值不一样,会导致CAS失败,失败之后,进入一个无限循环,再次获取值,接着执行CAS操作!
通过这个机制,不需要加锁这么重量级的机制,也可以用轻量级的方式实现多个线程安全的并发的修改某个数值。
四、CAS的优化
CAS有没有问题呢?肯定是有的。比如说大量的线程同时并发修改一个AtomicInteger,可能有很多线程会不停的自旋,进入一个无限重复的循环中,这些线程不停地获取值,然后发起CAS操作,但是发现这个值被别人改过了,于是再次进入下一个循环,获取值,发起CAS操作又失败了,再次进入下一个循环。
在大量线程高并发更新AtomicInteger的时候,这种问题可能会比较明显,导致大量线程空循环,自旋转,性能和效率都不是特别好,Java 8推出了一个新的类,LongAdder,他是尝试使用分段CAS以及自动分段迁移的方式大幅度提升多线程高并发执行CAS操作的性能!
在LongAdder的底层实现中,首先有一个base值,开始多线程来不停的累加数值,都是对base进行累加的,接着如果发现并发更新的线程数量过多,就会开始施行分段CAS的机制,也就是内部会搞一个Cell数组,每个数组是一个数值分段,让大量的线程分别去对不同Cell内部的value值进行CAS累加操作,这样就把CAS计算压力分散到了不同的Cell分段数值中了,所以大幅度的降低多线程并发更新同一个数值时出现的无限循环的问题,提升了多线程并发更新数值的性能和效率!
内部实现自动分段迁移的机制,如果某个Cell的value执行CAS失败了,那么就会自动去找另外一个Cell分段内的value值进行CAS操作,这样也解决了线程空旋转、自旋不停等待执行CAS操作的问题,让一个线程过来执行CAS时可以尽快的完成这个操作。
最后如果要从LongAdder中获取当前累加的总值,就会把base值和所有Cell分段数值加起来返回给你。
五、思考和总结
高并发访问下的分段处理机制,在很多地方都有类似的思想体现!因为高并发中的分段处理机制实际上是一个很常见和常用的并发优化手段,比如生成主健的Sequence技术,都是有异曲同工之妙的。