LongAdder

本文介绍了LongAdder的设计理念及其实现方式,对比AtomicLong,LongAdder通过分段计数减少CAS冲突,适用于高并发环境。文章详细解析了其内部结构与核心方法,并解释了如何在并发环境下高效地获取总和。

LongAdder是JDK1.8新增的原子性操作;用于弥补高并发环境下AtomicLong的效率变低的情况。

AtomicLong使用CAS自旋锁实现,但是在高并发的场景下,会导致大量线程轮询,造成CPU的浪费,性能下降。

public final int getAndAddInt(Object var1, long var2, int var4) {
	int var5;
	do {
		var5 = this.getIntVolatile(var1, var2);
	} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

	return var5;
}

LongAdder的引入可以减少CAS冲突,重试次数。

LongAdder的设计思想在于 分段, 将AtomicLong的存储结果的value热点数据进行分散。将对于value的操作分散到数组中的不同位置;最后返回结果的时候进行sum求和,减少CAS冲突。

 在并发不高的情况下,线程都是直接通过CAS直接操作base的;并发过高,分散操作到cells中;

volatile保证了变量在线程之间的可见性。

/**
 * Base value, used mainly when there is no contention, but also as
 * a fallback during table initialization races. Updated via CAS.
 */
transient volatile long base;

transient volatile Cell[] cells;

当要获取LongAdder中的值时: 进行求和, base + cells 

惰性求值:

        只用在 longValue()的时候才会累加获取。底层调用sum()方法;

        而AtomicLong每次 incrementAndGet()的时候都会直接返回修改后的值,具有额外开销

public long longValue() {
	return sum();
}

public long sum() {
	Cell[] as = cells; Cell a;
	long sum = base;
	if (as != null) {
		for (int i = 0; i < as.length; ++i) {
			if ((a = as[i]) != null)
				sum += a.value;
		}
	}
	return sum;
}

sum操作在并发更新的时候可能产生数据不一致。 

参考链接:

LongAdder源码解析_兴趣使然的草帽路飞的博客-优快云博客

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值