天天看点

三.多线程JUC篇-3.5 LongAdder

1.LongAdder原理

LongAdder是根据ConcurrentHashMap这类为并发设计的类的基本原理——锁分段,来实现的,它里面维护一组按需分配的计数单元,并发计数时,不同的线程可以在不同的计数单元上进行计数,这样减少了线程竞争,提高了并发效率。本质上是用空间换时间的思想,不过在实际高并发情况中消耗的空间可以忽略不计。

三.多线程JUC篇-3.5 LongAdder

使用LongAdder时,内部维护了多个Cell变量,每个Cell里面有一个初始值为0的long型变量,这样同时争取一个变量的线程就变少了,而是分散成对多个变量的竞争,减少了失败次数。如果竞争某个Cell变量失败,它不会一直在这个Cell变量上自旋CAS重试,而是尝试在其他的Cell变量上进行CAS尝试,这个改变增加了当前线程重试CAS成功的可能性。最后,在获取LongAdder当前值时,是把所有Cell变量的value值累加后再加上base返回的,即:它的 sum 是 base + 各个 Cell 中 value 的总和。

2.与AtomicLong比较

  • 相比较于 AtomicLong,它在高并发时更高效,因为 AtomicLong 在自增失败时会自旋,直到成功。这会导致高并发时,可能有非常多的无意义的自旋。
  • 在低并发下AtomicLong稍微有优势,但在高并发下,LongAdder优势明显。
  • LongAdder的缺点在统计的时候如果有并发更新,可能导致统计的数据有误差,所以如果对准确性要求比较高的话,还是使用AtomicLong。

继续阅读