[备份] Java并发之LongAdder源码浅析

介绍

高并发下做数据统计,如果采用AtomicLong的方式会存在问题

img

AtomicLong.getAndIncrement方法使用到unsafe类

跟入unsafe类看到底层实现是CAS。高并发情况下,多个线程同时卡在循环中,效率过低。另外CAS有ABA问题(原理和解决参考上一篇文章)

img

于是出现了一个新的类:LongAddr

 

源码

Striped64

首先来看Cell数组中的Cell是什么

Cell数组长度条件取决于CPU数量,后续分析

没有发生竞争或cells扩容时,需要写入base

初始化cells或扩容都需要锁,0表示无锁,1表示其他线程持有锁

当前线程的哈希值

 

add

LongAdderadd方法进入

 

longAccumulate

这是LongAdder的核心方法,进入该方法的三大条件:

  1. cells未被初始化,说明发生了竞争,需要初始化
  2. 当前线程对应下标cell为空,需要创建longAccumulate支持
  3. cas操作失败,说明当前线程对应cell有竞争,需要重试或扩容

 

sum

获取的方法就很简单了,base加cell数组的value