为什么需要LongAdder?
理论上,我们已经拥有了原子性数据的AtomicLong,但是AtomicLong在很高并发的情况下,使用CAS的效率不是很高,LongAdder内部将一个long分成多个cell,每个线程可以对一个cell操作,如果需要取出long数据则求和即可,这样增强了在高并发情况下的效率。
内部实现
- 只能做累加,或者自增自减操作,不能做其他操作
- 用一个Cell数组来存放分段数据值大小,Cell数组中很简单只有一个value表示存放的值
- sum方法用于返回当前计数值,返回所有Cell中value的和
- 多个线程会进行hash,对不同的Cell元素进行操作
- 内部有扩容方法,增加更多的Cell元素
提问
1. 为什么只能做累加?
LongAdder是只能做累加的,但是同一个父类Striped64下面还有其他的类,比如LongAccumulator,可以通过构造器进行更多的操作,但是都仅限此操作
LongAccumulator(LongBinaryOperator accumulatorFunction,
long identity)
构造器中的accumulatorFunction是函数式接口,用labmda表达式实现即可。其他的类还有DoubleAdder和DoubleAccumulator。
2. 为什么用Cell数组而不是long数组?
Cell数组仅含有value属性表示long的数据,在进行扩容的时候,一个线程进行扩容,另一个线程没意识到扩容,继续进行操作。因为扩容之后只是在新数组中生成Cell的饮用,Cell本身是不会变化的。但是long是栈中存储,可能会发生数据丢失的问题。