java8之后,新增了专门用于计数的类,LongAccumulator,LongAdder的性能高于AtomicLong。
LongAdder 性能 > AtomicLong 性能
性能高的原因:如果都往一个共享变量上面进行累加,那么比较重试的次数肯定就多;如果分成几个变量分别进行累加就优化了。在竞争时设置了多个累加单元。Thread-0累加Cell[0],而Thread-1累加Cell[1]....最后将结果汇总。这样它们在累加时操作不同的Cell变量,因此减少了CAS重试失败,从而提高性能。
cells 累加单元数组,懒惰初始化
base 基础值,如果没有竞争,则用cas累加这个阈
在cells 创建或者扩容时,置为1,表示加锁。
Cell类的源码:
@sun.misc.Contended注解,防止缓存行伪共享
缓存的加入会造成数据副本的产生,即同一份数据会缓存在不同核心的缓存行中。
CPU要保证数据的一致性,如果某个CPU核心更改了数据,其他CPU核心对应的整个缓存行必须失效。