CAS原理

CAS compare and set 先比较再设置。

比如有三个线程去修改一个变量,进行累加的操作,第一次三个线程都会去获取值,如果开始都是1,那么当一个线程去修改的时候会去先去看这个值还是1吗?如果是1,接着下面的流程,其他线程如果也同时对变量进行修改时,他会去交易当前值是否为1,如果不是会失败,进行循环的去获取值。每次保证是原子操作。

CAS原理

就是所谓Atomic原子类的原理,没有基于加锁机制串行化,而是基于CAS机制:先获取一个值,然后发起CAS,比较这个值被人改过没?如果没有,就更改值!这个CAS是原子的,别人不会打断你!
通过这个机制,不需要加锁这么重量级的机制,也可以用轻量级的方式实现多个线程安全的并发的修改某个数值。

但是cas会出现一个问题,当大量线程进行atomicInteger修改时,会导致大量线程进行一个重复的循环;空循环,自旋转,性能和效率都不是特别好;
java8 针对这个问题做了一个优化,加了一个LongAdder, 分段cas和自动分段迁移来提升线程高并发情况下cas的性能;

CAS原理

在LongAdder的底层实现中,首先有一个base值,刚开始多线程来不停的累加数值,都是对base进行累加的,比如刚开始累加成了base = 5。

接着如果发现并发更新的线程数量过多,就会开始施行分段CAS的机制,也就是内部会搞一个Cell数组,每个数组是一个数值分段。

这时,让大量的线程分别去对不同Cell内部的value值进行CAS累加操作,这样就把CAS计算压力分散到了不同的Cell分段数值中了!

这样就可以大幅度的降低多线程并发更新同一个数值时出现的无限循环的问题,大幅度提升了多线程并发更新数值的性能和效率!

而且他内部实现了自动分段迁移的机制,也就是如果某个Cell的value执行CAS失败了,那么就会自动去找另外一个Cell分段内的value值进行CAS操作。

这样也解决了线程空旋转、自旋不停等待执行CAS操作的问题,让一个线程过来执行CAS时可以尽快的完成这个操作。

最后,如果你要从LongAdder中获取当前累加的总值,就会把base值和所有Cell分段数值加起来返回给你。