当前位置:   article > 正文

【小笔记】LongAdder和AtomicLong_longadder atomiclong

longadder atomiclong

多个线程更新用于收集统计信息而不是细粒度同步控制的公共和时,LongAdder通常比AtomicLong更可取。在低级别争用下,这两个类具有相似的特性。但在高争用情况下,LongAdder的预期吞吐量明显更高,这是以更高的空间消耗为代价的。
AtomicLong内部直接使用CAS完成原子化加算:

public final long getAndAdd(long delta) {
	return unsafe.getAndAddLong(this, valueOffset, delta);
}

public final long getAndAddLong(Object var1, long var2, long var4) {
	long var6;
	do {
		var6 = this.getLongVolatile(var1, var2);
	} while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));

	return var6;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这种方式在低并发的情况下不会自旋太多次就能成功,损失有限,但是随着并发量的提升,CAS失败导致的自旋次数会急剧上升,这会导致AtomicLong的效率急剧下降,大量的自旋也会导致CPU的严重浪费。这种方式的根本原因就是因为多个线程争抢一个资源导致的,LongAdder对此做出了优化,将一个变量拆分成多个变量:
在这里插入图片描述
LongAdder并不是一开始就进行遍历拆分,最初他会和AtomicLong一样,维护一个变量进行CAS加算,只有出现并发导致CAS失败时才会进行拆分。
cell初始有两个,后续会根据争用情况进行二倍扩容。这是拆分资源的方式能大大提升高并发时的处理效率,缺点是需要更多的内存空间,是一种以空间换时间的方式。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/363138
推荐阅读
  

闽ICP备14008679号