JUC_Striped64

Striped64 是一个抽象类,继承了 Number 类。它是 Java 并发包中的一部分,用于支持多线程环境下的原子性操作。

Striped64 中,使用 int 数组 baseCounterCell 数组 cells 来存储计数器的值。其中,base 数组存储未被分配到 CounterCell 的线程的计数器值,而 cells 数组则存储已经被分配到 CounterCell 的线程的计数器值。通过使用数组来存储计数器值,可以减少锁的竞争,从而提高并发性能。

Striped64 实现了一些基本的原子操作,例如加、减、乘、除等。它内部实现使用了无锁算法(CAS),保证了操作的原子性和线程安全性。

Number 是 Java 中的一个抽象类,它是所有数字类型的父类,包括整数类型和浮点类型。Number 中定义了一系列抽象方法,包括将数字转换为特定数据类型的方法,例如 intValue()longValue()floatValue()doubleValue() 等。

由于 Striped64 继承了 Number 类,因此它也具有将数字转换为特定类型的方法,可以方便地将计数器的值转换为 int、long、float 或 double 类型。

示例代码:

java
import java.util.concurrent.atomic.AtomicInteger;

public abstract class Striped64 extends Number {
    private static final long serialVersionUID = -1182697631144950088L;

    // base 数组用于存储未分配到 CounterCell 的线程的计数器值
    volatile long base;
    // cells 数组用于存储已经分配到 CounterCell 的线程的计数器值
    volatile transient CounterCell[] cells;

    // 使用无锁算法添加 delta 到 base 或 cells 中指定下标的计数器值
    final void longAccumulate(long x, LongBinaryOperator fn, boolean wasUncontended) {
        int h;
        if ((h = getProbe()) == 0) {
            ThreadLocalRandom.current(); // 强制初始化 ThreadLocalRandom
            h = getProbe();
            wasUncontended = true;
        }
        boolean collide = false; // 如果 hash 冲突,即当前线程在 cells 中对应的元素已被占用,值为 true
        for (;;) {
            CounterCell[] as;
            CounterCell a;
            int n;
            long v;
            if ((as = cells) != null && (n = as.length) > 0) {
                if ((a = as[(n - 1) & h]) == null) {
                    if (cellsBusy == 0) { // 当前没有其他线程修改 cells 数组,尝试为当前线程分配 CounterCell
                        CounterCell r = new CounterCell(x);
                        if (cellsBusy == 0 && casCellsBusy()) { // 成功获取 cellsBusy 锁
                            boolean created = false;
                            try {
                                CounterCell[] rs;
                                int m, j;
                                if ((rs = cells) != null && (m = rs.length) > 0
                                        && rs[j = (m - 1) & h] == null) { // 仍然没有其他线程修改 cells 数组,将 CounterCell 设置到 cells 数组中
                                    rs[j] = r;
                                    created = true;
                                }
                            } finally {
                                cellsBusy = 0;
                            }
                            if (created) {
                                break;
                            }
                            continue; // 竞争失败,继续循环
                        }
                    }
                    collide = false;
                } else if (!wasUncontended) {
                    wasUncontended = true;
                } else if (a.cas(v = a.value, ((fn == null) ? v + x : fn.applyAsLong(v, x)))) { // 使用 CAS 更新计数器值
                    break;
                } else if (n >= NCPU || cells != as) { // 由于 hash 冲突,在 cells 中对应的元素已被占用,尝试随机获取一个空闲的元素
                    collide = false;
                } else if (!collide) { // 记录当前线程在 cells 数组中对应的元素已被占用
                    collide = true;
                } else if (cellsBusy == 0 && casCellsBusy()) { // 成功获取 cellsBusy 锁
                    try {
                        if (cells == as) { // double check
                            CounterCell[] rs = new CounterCell[n << 1];
                            for (int i = 0; i < n; ++i) {
                                rs[i] = as[i];
                            }
                            cells = rs;
                        }
                    } finally {
                        cellsBusy = 0;
                    }
                    collide = false;
                    continue; // 竞争失败,继续循环
                }
                h = advanceProbe(h);
            } else if (cellsBusy == 0 && cells == as && casCellsBusy()) { // 成功获取 cellsBusy 锁
                boolean init = false;
                try {
                    if (cells == as) { // double check
                        CounterCell[] rs = new CounterCell[2];
                        rs[h & 1] = new CounterCell(x);
                        cells = rs;
                        init = true;
                    }
                } finally {
                    cellsBusy = 0;
                }
                if (init) {
                    break;
                }
            } else if (casBase(v = base, ((fn == null) ? v + x : fn.applyAsLong(v, x)))) { // 通过 CAS 更新 base 中的计数器值
                break;
            }
        }
    }

    // 获取当前线程对应的 hash 值,用于将计数器添加到 cells 数组中指定下标的位置
    static final int getProbe() {
        return UNSAFE.getInt(Thread.currentThread(), PROBE);
    }

    // 随机化当前线程的 hash 值,用于避免不同线程的索引值冲突
    static final int advanceProbe(int probe) {
        probe ^= probe << 13; // xorshift
        probe ^= probe >>> 17;
        probe ^= probe << 5;
        UNSAFE.putInt(Thread.currentThread(), PROBE, probe);
        return probe;
    }

    // AtomicLong 中用于控制对 cells 数组的竞争
    static final long CELLSBUSY = 0x00000000L;
    volatile long cellsBusy;

    // 获取对 cells 数组的独占锁,避免多线程修改 cells 数组时发生竞争
    final boolean casCellsBusy() {
        return UNSAFE.compareAndSwapLong(this, CELLSBUSY, 0, 1);
    }

    // 计算集合中所有 CounterCell 的值的总和
    final long sumCells() {
        CounterCell[] as = cells;
        long sum = base;
        if (as != null) {
            int n = as.length;
            for (int i = 0; i < n; ++i) {
                CounterCell a = as[i];
                if (a != null) {
                    sum += a.value;
                }
            }
        }
        return sum;
    }
}

// 定义 CounterCell 类,用于存储已经被分配到的线程的计数器值
class CounterCell {
    private static final Unsafe UNSAFE;
    private static final long valueOffset;

    static {
        try {
            UNSAFE = getUnsafe();
            Class<?> ak = CounterCell.class;
            valueOffset = UNSAFE.objectFieldOffset(ak.getDeclaredField("value"));
        } catch (Exception e) {
            throw new Error(e);
        }
    }

    // 使用 CAS 更新计数器值
    final boolean cas(long cmp, long val) {
        return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
    }

    volatile long value;

    CounterCell(long x) {
        value = x;
    }

    // Unsafe 相关操作
    private static Unsafe getUnsafe() {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            return (Unsafe) theUnsafe.get(null);
        } catch (Exception e) {
            throw new Error(e);
        }
    }
}

在上述代码中,Striped64 实现了 longAccumulate 方法,用于实现多线程环境下的原子操作。其中使用了无锁算法(CAS)来保证线程安全,并且继承自 Number 类,具有将计数器值转换为各种数值类型的方法。另外,定义了 CounterCell 类,用于存储已经被分配到的线程的计数器值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值