编程语言
首页 > 编程语言> > Java中的并发计数器LongAdder

Java中的并发计数器LongAdder

作者:互联网

并发计数器LongAdder

基本概念

在这里插入图片描述

Striped64

在这里插入图片描述

Striped64重要成员变量

	/**
     * 存放元素cell的Hash表,大小为2的整数次幂
     */
    transient volatile Cell[] cells;

    /**
     * 基础值:
     * - 在没有竞争的情况下,累加的数通过CAS累加到base上
     * - 在数组cells初始化过程时,数组中的元素cell不可用。此时累加的数会尝试通过CAS累加到base上
     */
    transient volatile long base;

    /**
     * 自旋锁,通过CAS加锁
     * 用于创建和扩容数组cells的Hash表
     */
    transient volatile int cellsBusy;

cells

cellsBusy

base

内部类Cell

CPU缓存架构

在这里插入图片描述

缓存行cache line

在这里插入图片描述

在这里插入图片描述

伪共享

Striped64重要方法

longAccumulate

/**
 * 处理涉及初始化,扩容,创建新的Cell对象和竞争的更新情况
 *  
 * @param x 需要累加的值
 * @param fn 更新函数,可以为null。用于累加操作
 * @param wasUncontended 如果CAS操作在调用前执行失败则返回false。表明调用方法之前的add()方法是否没有发生争用
 */
final void longAccumulate(long x, LongBinaryOperator fn, boolean wasUncontended);

LongAdder

LongAdder重要方法

add

/**
 * 对指定的值累加
 *  
 * @param x 需要累加的值
 */
public void add(long x);

总结

hash的值生成

	@jdk.internal.vm.annotation.Contended("tlr")
    int threadLocalRandomProbe;
	/**
     * 返回当前线程的probe值
     * 由于包装的限制,从ThreadLocalRandom中复制
     */
	static final int getProbe() {
        return (int) THREAD_PROBE.get(Thread.currentThread());
    }

threadLocalRandomProbe初始化

		if ((h = getProbe()) == 0) {
            // ThreadLocalRandom类强制初始化
            ThreadLocalRandom.current(); // force initialization
            // 设置h的值为0x9e3779b9
            h = getProbe();
            // 将没有争用的标识设置为true
            wasUncontended = true;
        }
	/**
	 * 返回当前线程的ThreadLocalRandom
	 */
	public static ThreadLocalRandom current() {
        if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
            localInit();
        return instance;
    }
	/**
	 * 为当前线程初始化线程字段
	 */
	static final void localInit() {
        int p = probeGenerator.addAndGet(PROBE_INCREMENT);
        // 跳过p为0的值
        int probe = (p == 0) ? 1 : p; // skip 0
        long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
        // 获取当前线程
        Thread t = Thread.currentThread();
        U.putLong(t, SEED, seed);
        // 将probe的值更新为probeGenerator的值
        U.putInt(t, PROBE, probe);
    }

threadLocalRandomProbe重新生成

	static final int advanceProbe(int probe) {
        probe ^= probe << 13;   // xorshift
        probe ^= probe >>> 17;
        probe ^= probe << 5;
        THREAD_PROBE.set(Thread.currentThread(), probe);
        return probe;
    }

标签:缓存,Java,变量,cells,cache,累加,计数器,LongAdder,CPU
来源: https://blog.csdn.net/JewaveOxford/article/details/119211631