LongAdder和LongAccumulator
所属分类 java
浏览量 1096
AtomicLong CAS提供非阻塞的原子操作
CAS失败 自旋
多线程同时竞争读写同一个变量 高并发 消耗cpu
public final long incrementAndGet() {
for (;;) {
long current = get();
long next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
LongAdder 把一个变量 变成 多个变量
public class LongAdder extends Striped64
// 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;
// Table of cells. When non-null, size is a power of 2.
transient volatile Cell[] cells;
// Spinlock (locked via CAS) used when resizing and/or creating Cells.
transient volatile int cellsBusy;
@sun.misc.Contended static final class Cell {
volatile long value;
Cell(long x) { value = x; }
final boolean cas(long cmp, long val) {
return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
}
// Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
private static final long valueOffset;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class> ak = Cell.class;
valueOffset = UNSAFE.objectFieldOffset
(ak.getDeclaredField("value"));
} catch (Exception e) {
throw new Error(e);
}
}
}
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;
}
LongAdder 是 LongAccumulator 的特例
public class AtomicTest {
static final AtomicLong count1 = new AtomicLong(0);
static final LongAdder count2 = new LongAdder();
static final LongAccumulator count3 = new LongAccumulator(new MyLongBinaryOperator(),0);
public static void main(String[] args) throws Exception {
count1.getAndIncrement();
count2.add(1);
count3.accumulate(1);
System.out.println(count1.get()+","+count2.longValue()+","+count3.longValue());
}
private static class MyLongBinaryOperator implements LongBinaryOperator{
@Override
public long applyAsLong(long left, long right) {
return left + right;
}
}
}
上一篇
下一篇
JVM GC 过程简介
micrometer使用
zookeeper 与 dubbo
mysql面试题
redis面试题
cassandra架构要点