首页  

LongAdder和LongAccumulator     所属分类 java 浏览量 949
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架构要点