LongAdder详解

出现背景

在以往并发情况下进行累加计数时通常使用AtomicLong,因为其底层是基于cas实现的,高并发下对单一变量进行CAS操作,从而保证其原子性。其它的线程都会进行不断自旋,这就产生了问题,随着并发线程数增加,等待线程的自旋时间也会大幅增加,白白造成了CPU资源的浪费;

LongAdder问世

JDK1.8提供了LongAdder类,此类专门用来解决上述提到的问题,LongAdder 继承 Striped64 和 Number,LongAdder是一种以空间换时间的解决方案。其内部维护了一个值base,和一个cell数组,当线程写base有冲突时,将其写入数组的一个cell中(初始值为0)。将base和所有cell中的值求和就能得到最终LongAdder的值。

cells的长度就是cpu的核数,因为一个CPU同一时间只能执行一个线程,如果cells数组长度 大于 CPU数量,并不能提高并发数,且造成空间的浪费。
base:在没有发生过竞争时,数据会累加到base上。 或者,当cells扩容时,是需要将数据写到base中的。

总结

  • LongAdder是一种以空间换时间的解决方案,其在高并发,竞争大的情况下性能更优。
  • 但是,sum方法拿到的只是接近值,追求最终一致性。如果业务场景追求高精度,高准确性,用AtomicLong。
posted @ 2023-02-17 15:59  HexThinking  阅读(315)  评论(0编辑  收藏  举报