JDK 8 AtomicIntegerArray 源码详解(详细注释版)

JDK 8 AtomicIntegerArray 源码详解(详细注释版)

1. 类定义和基本属性

public class AtomicIntegerArray implements java.io.Serializable {
    
    // 序列化版本号
    private static final long serialVersionUID = 2862133569453604235L;

    /**
     * Unsafe类实例,提供底层的原子操作
     * 通过Unsafe可以直接操作内存地址,实现CAS等原子操作
     */
    private static final sun.misc.Unsafe unsafe = getUnsafe();

    /**
     * 数组的第一个元素在内存中的偏移量
     * 用于计算数组元素的内存地址
     */
    private static final int base = unsafe.arrayBaseOffset(int[].class);

    /**
     * 数组元素之间的地址增量(步长)
     * 用于计算数组中任意元素的内存地址
     */
    private static final int shift;

    /**
     * 静态初始化块,计算shift值
     * 根据数组元素的地址增量确定位移量
     */
    static {
        int scale = unsafe.arrayIndexScale(int[].class);
        if ((scale & (scale - 1)) != 0)
            throw new Error("data type scale not a power of two");
        shift = 31 - Integer.numberOfLeadingZeros(scale);
    }

    /**
     * 获取Unsafe实例的方法
     * 由于Unsafe类的特殊性,需要通过反射获取实例
     * @return Unsafe实例
     */
    private static sun.misc.Unsafe getUnsafe() {
        try {
            return sun.misc.Unsafe.getUnsafe();
        } catch (SecurityException se) {
            try {
                return java.security.AccessController.doPrivileged
                    (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
                        public sun.misc.Unsafe run() throws Exception {
                            Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
                            for (java.lang.reflect.Field f : k.getDeclaredFields()) {
                                f.setAccessible(true);
                                Object x = f.get(null);
                                if (k.isInstance(x))
                                    return k.cast(x);
                            }
                            throw new NoSuchFieldError("the Unsafe");
                        }});
            } catch (java.security.PrivilegedActionException e) {
                throw new RuntimeException("Could not initialize intrinsics",
                                           e.getCause());
            }
        }
    }

    /**
     * 实际存储的int数组
     * 使用volatile修饰确保内存可见性
     * 所有原子操作都是针对这个数组进行的
     */
    private final int[] array;

    /**
     * 构造方法,创建指定长度的AtomicIntegerArray
     * @param length 数组长度
     * 
     * 初始化过程:
     * 1. 创建指定长度的int数组
     * 2. 数组元素初始化为0(int的默认值)
     * 3. volatile语义确保对其他线程的可见性
     * 
     * @throws NegativeArraySizeException 如果length为负数
     */
    public AtomicIntegerArray(int length) {
        array = new int[length];
    }

    /**
     * 构造方法,从给定数组创建AtomicIntegerArray
     * @param array 给定的int数组
     * 
     * 初始化过程:
     * 1. 复制给定数组的内容
     * 2. 创建新的int数组存储副本
     * 3. volatile语义确保对其他线程的可见性
     * 
     * @throws NullPointerException 如果array为null
     */
    public AtomicIntegerArray(int[] array) {
        // 复制数组内容,避免外部修改影响内部状态
        this.array = Arrays.copyOf(array, array.length);
    }

    /**
     * 获取数组长度
     * 
     * 时间复杂度:O(1)
     * 线程安全性:完全线程安全
     * 
     * @return 数组长度
     */
    public final int length() {
        return array.length;
    }

    /**
     * 获取指定索引位置的值
     * 通过Unsafe直接读取数组元素,保证获取最新的值
     * 
     * 时间复杂度:O(1)
     * 线程安全性:完全线程安全
     * 
     * @param i 索引位置
     * @return 指定位置的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int get(int i) {
        return getRaw(checkedByteOffset(i));
    }

    /**
     * 原子地设置指定索引位置的值并返回旧值
     * 这是一个原子操作,保证读取和设置的原子性
     * 
     * 操作过程:
     * 1. 读取指定位置的当前值
     * 2. 设置新值
     * 3. 返回旧值
     * 
     * 时间复杂度:O(1)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @param newValue 新值
     * @return 旧值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int getAndSet(int i, int newValue) {
        return getAndSetRaw(checkedByteOffset(i), newValue);
    }

    /**
     * 原子地比较并设置指定索引位置的值
     * 只有当当前值等于期望值时,才设置为新值
     * 
     * 操作过程:
     * 1. 比较指定位置的当前值和期望值
     * 2. 如果相等,将当前值设置为新值
     * 3. 返回比较结果
     * 
     * CAS操作特点:
     * - 无锁操作,性能优秀
     * - 乐观锁机制,避免阻塞
     * - 可能出现ABA问题
     * 
     * 时间复杂度:O(1)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @param expect 期望值
     * @param update 新值
     * @return 如果设置成功返回true,否则返回false
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final boolean compareAndSet(int i, int expect, int update) {
        return compareAndSetRaw(checkedByteOffset(i), expect, update);
    }

    /**
     * 弱原子地比较并设置指定索引位置的值
     * 与compareAndSet类似,但在某些平台上可能不提供完全的内存排序保证
     * 
     * 使用场景:
     * - 对内存排序要求不严格的场景
     * - 性能要求极高的场景
     * 
     * @param i 索引位置
     * @param expect 期望值
     * @param update 新值
     * @return 如果设置成功返回true,否则返回false
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final boolean weakCompareAndSet(int i, int expect, int update) {
        return compareAndSetRaw(checkedByteOffset(i), expect, update);
    }

2. 原子更新方法(详细注释)

    /**
     * 原子地增加1并返回旧值
     * 这是一个原子的自增操作
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 计算新值(当前值+1)
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回旧值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @return 增加前的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int getAndIncrement(int i) {
        return getAndAdd(i, 1);
    }

    /**
     * 原子地减少1并返回旧值
     * 这是一个原子的自减操作
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 计算新值(当前值-1)
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回旧值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @return 减少前的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int getAndDecrement(int i) {
        return getAndAdd(i, -1);
    }

    /**
     * 原子地增加指定值并返回旧值
     * 这是一个原子的加法操作
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 计算新值(当前值+delta)
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回旧值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @param delta 要增加的值
     * @return 增加前的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int getAndAdd(int i, int delta) {
        return getAndAddRaw(checkedByteOffset(i), delta);
    }

    /**
     * 原子地增加1并返回新值
     * 这是一个原子的自增操作
     * 
     * 与getAndIncrement的区别:
     * - getAndIncrement返回旧值
     * - incrementAndGet返回新值
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 计算新值(当前值+1)
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回新值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @return 增加后的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int incrementAndGet(int i) {
        return addAndGet(i, 1);
    }

    /**
     * 原子地减少1并返回新值
     * 这是一个原子的自减操作
     * 
     * 与getAndDecrement的区别:
     * - getAndDecrement返回旧值
     * - decrementAndGet返回新值
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 计算新值(当前值-1)
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回新值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @return 减少后的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int decrementAndGet(int i) {
        return addAndGet(i, -1);
    }

    /**
     * 原子地增加指定值并返回新值
     * 这是一个原子的加法操作
     * 
     * 与getAndAdd的区别:
     * - getAndAdd返回旧值
     * - addAndGet返回新值
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 计算新值(当前值+delta)
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回新值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @param delta 要增加的值
     * @return 增加后的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int addAndGet(int i, int delta) {
        return getAndAddRaw(checkedByteOffset(i), delta) + delta;
    }

    /**
     * 原子地更新值,使用指定的更新函数
     * 这是Java 8新增的方法,支持函数式编程
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 使用updateFunction计算新值
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回新值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @param updateFunction 更新函数
     * @return 更新后的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int updateAndGet(int i, IntUnaryOperator updateFunction) {
        long offset = checkedByteOffset(i);
        int prev, next;
        do {
            prev = getRaw(offset);
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSetRaw(offset, prev, next));
        return next;
    }

    /**
     * 原子地更新值,使用指定的更新函数
     * 返回更新前的值
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 使用updateFunction计算新值
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回旧值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @param updateFunction 更新函数
     * @return 更新前的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int getAndUpdate(int i, IntUnaryOperator updateFunction) {
        long offset = checkedByteOffset(i);
        int prev, next;
        do {
            prev = getRaw(offset);
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSetRaw(offset, prev, next));
        return prev;
    }

    /**
     * 原子地累积值,使用指定的累积函数
     * 这是Java 8新增的方法,支持累积操作
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 使用accumulatorFunction计算累积值
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回新值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @param x 要累积的值
     * @param accumulatorFunction 累积函数
     * @return 累积后的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int accumulateAndGet(int i, int x,
                                      IntBinaryOperator accumulatorFunction) {
        long offset = checkedByteOffset(i);
        int prev, next;
        do {
            prev = getRaw(offset);
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSetRaw(offset, prev, next));
        return next;
    }

    /**
     * 原子地累积值,使用指定的累积函数
     * 返回累积前的值
     * 
     * 操作过程:
     * 1. 获取指定位置的当前值
     * 2. 使用accumulatorFunction计算累积值
     * 3. 使用CAS操作更新值
     * 4. 如果CAS失败,重复步骤1-3
     * 5. 返回旧值
     * 
     * 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
     * 线程安全性:完全原子性
     * 
     * @param i 索引位置
     * @param x 要累积的值
     * @param accumulatorFunction 累积函数
     * @return 累积前的值
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    public final int getAndAccumulate(int i, int x,
                                      IntBinaryOperator accumulatorFunction) {
        long offset = checkedByteOffset(i);
        int prev, next;
        do {
            prev = getRaw(offset);
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSetRaw(offset, prev, next));
        return prev;
    }

3. 辅助方法(详细注释)

    /**
     * 检查数组索引并计算字节偏移量
     * 确保索引在有效范围内,并计算对应的内存偏移量
     * 
     * @param i 数组索引
     * @return 对应的字节偏移量
     * @throws IndexOutOfBoundsException 如果索引越界
     */
    private long checkedByteOffset(int i) {
        if (i < 0 || i >= array.length)
            throw new IndexOutOfBoundsException("index " + i);
        return byteOffset(i);
    }

    /**
     * 计算数组索引对应的字节偏移量
     * 使用base偏移量和shift计算元素的内存地址
     * 
     * @param i 数组索引
     * @return 对应的字节偏移量
     */
    private static long byteOffset(int i) {
        return ((long) i << shift) + base;
    }

    /**
     * 通过Unsafe获取指定偏移量位置的值
     * 
     * @param offset 内存偏移量
     * @return 指定位置的值
     */
    private int getRaw(long offset) {
        return unsafe.getIntVolatile(array, offset);
    }

    /**
     * 通过Unsafe原子地设置指定偏移量位置的值并返回旧值
     * 
     * @param offset 内存偏移量
     * @param newValue 新值
     * @return 旧值
     */
    private int getAndSetRaw(long offset, int newValue) {
        return unsafe.getAndSetInt(array, offset, newValue);
    }

    /**
     * 通过Unsafe原子地比较并设置指定偏移量位置的值
     * 
     * @param offset 内存偏移量
     * @param expect 期望值
     * @param update 新值
     * @return 如果设置成功返回true,否则返回false
     */
    private boolean compareAndSetRaw(long offset, int expect, int update) {
        return unsafe.compareAndSwapInt(array, offset, expect, update);
    }

    /**
     * 通过Unsafe原子地增加指定偏移量位置的值并返回旧值
     * 
     * @param offset 内存偏移量
     * @param delta 要增加的值
     * @return 旧值
     */
    private int getAndAddRaw(long offset, int delta) {
        return unsafe.getAndAddInt(array, offset, delta);
    }

4. 字符串表示方法(详细注释)

    /**
     * 返回对象的字符串表示
     * 重写Object类的toString方法
     * 
     * @return 数组内容的字符串表示
     */
    public String toString() {
        int iMax = array.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(get(i));
            if (i == iMax)
                return b.append(']').toString();
            b.append(',').append(' ');
        }
    }

    /**
     * 计算对象的哈希码
     * 重写Object类的hashCode方法
     * 
     * @return 对象的哈希码
     */
    public int hashCode() {
        int result = 1;
        for (int i = 0; i < array.length; i++) {
            int element = get(i);
            result = 31 * result + element;
        }
        return result;
    }

    /**
     * 比较两个AtomicIntegerArray对象是否相等
     * 重写Object类的equals方法
     * 
     * @param obj 要比较的对象
     * @return 如果相等返回true,否则返回false
     */
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!(obj instanceof AtomicIntegerArray))
            return false;

        AtomicIntegerArray that = (AtomicIntegerArray) obj;
        if (array.length != that.array.length)
            return false;

        for (int i = 0; i < array.length; i++)
            if (get(i) != that.get(i))
                return false;

        return true;
    }

5. AtomicIntegerArray 的特点分析

核心设计理念:

/**
 * AtomicIntegerArray的核心设计思想:
 * 
 * 1. 数组原子操作:
 *    - 提供对数组元素的原子操作
 *    - 每个元素都可以独立进行原子操作
 *    - 支持细粒度的并发控制
 * 
 * 2. 无锁编程:
 *    - 使用CAS(Compare-And-Swap)操作实现原子性
 *    - 避免传统锁的开销和阻塞
 *    - 提供乐观锁机制
 * 
 * 3. volatile语义:
 *    - array字段使用final修饰,数组引用不可变
 *    - 数组元素通过Unsafe的volatile操作保证可见性
 *    - 确保读操作获取最新值
 * 
 * 4. Unsafe支持:
 *    - 使用sun.misc.Unsafe类提供底层原子操作
 *    - 直接操作数组元素的内存地址,性能优异
 *    - 绕过JVM的常规访问控制
 * 
 * 5. 偏移量机制:
 *    - 通过数组基地址和元素偏移量直接访问内存
 *    - 避免反射开销
 *    - 提供精确的内存操作
 * 
 * 6. 自旋重试:
 *    - CAS失败时自动重试
 *    - 保证操作的最终成功
 *    - 适用于竞争不激烈的场景
 * 
 * 7. 函数式支持:
 *    - Java 8新增函数式更新方法
 *    - 支持lambda表达式
 *    - 提供更灵活的原子操作
 * 
 * 8. 边界检查:
 *    - 所有操作都进行索引边界检查
 *    - 防止数组越界异常
 *    - 提供安全的数组访问
 * 
 * 适用场景:
 * - 多线程环境下的计数器数组
 * - 状态标志数组
 * - 需要原子操作的整数数组
 * - 高并发环境下的数组操作
 * - 需要细粒度并发控制的场景
 */

性能特征分析:

/**
 * AtomicIntegerArray的性能特征:
 * 
 * 时间复杂度:
 * - get(i): O(1) - 直接读取数组元素
 * - compareAndSet(i, expect, update): O(1) 平均,O(∞) 最坏
 * - getAndIncrement(i): O(1) 平均,O(∞) 最坏
 * - incrementAndGet(i): O(1) 平均,O(∞) 最坏
 * - getAndAdd(i, delta): O(1) 平均,O(∞) 最坏
 * - addAndGet(i, delta): O(1) 平均,O(∞) 最坏
 * 
 * 空间复杂度:
 * - O(n) - 需要存储n个int值
 * - 每个元素都有固定的内存开销
 * 
 * 并发特性:
 * - 完全线程安全
 * - 每个数组元素可以独立进行原子操作
 * - 无锁设计,避免线程阻塞
 * - 乐观锁机制,适用于低竞争场景
 * - 高竞争场景下可能出现自旋开销
 * 
 * 与synchronized数组对比:
 * - 无竞争:AtomicIntegerArray > synchronized数组
 * - 低竞争:AtomicIntegerArray > synchronized数组
 * - 高竞争:AtomicIntegerArray可能 < synchronized数组
 * - 内存开销:AtomicIntegerArray < synchronized数组
 * 
 * 与AtomicInteger[]对比:
 * - 功能相似:都提供原子操作
 * - 内存使用:AtomicIntegerArray < AtomicInteger[]
 * - 性能:AtomicIntegerArray ≥ AtomicInteger[]
 * - 管理复杂度:AtomicIntegerArray < AtomicInteger[]
 * 
 * CAS操作特点:
 * - 乐观锁:假设没有冲突,冲突时重试
 * - 非阻塞:不会阻塞其他线程
 * - ABA问题:需要额外机制解决
 * - 自旋开销:高竞争时CPU使用率可能较高
 * 
 * 内存使用:
 * - 每个实例存储一个数组引用
 * - 数组元素通过volatile保证可见性
 * - 及时GC,避免内存泄漏
 * 
 * 适用性:
 * - 数组元素原子操作:性能优异
 * - 高频数组更新场景:性能优异
 * - 复杂同步逻辑:可能不如锁机制
 * - 需要精确控制:比锁更灵活
 */

6. 使用示例和最佳实践

/**
 * 使用示例:
 * 
 * // 基本使用
 * AtomicIntegerArray array = new AtomicIntegerArray(10);
 * 
 * // 原子设置和获取
 * array.set(0, 100);
 * int value = array.get(0);
 * 
 * // 原子自增
 * int oldValue = array.getAndIncrement(0); // 返回旧值
 * int newValue = array.incrementAndGet(0); // 返回新值
 * 
 * // 原子自减
 * int oldValue2 = array.getAndDecrement(0);
 * int newValue2 = array.decrementAndGet(0);
 * 
 * // 原子加法
 * int oldValue3 = array.getAndAdd(0, 5);
 * int newValue3 = array.addAndGet(0, 5);
 * 
 * // 比较并设置
 * boolean success = array.compareAndSet(0, 10, 20);
 * if (success) {
 *     System.out.println("Value updated successfully");
 * } else {
 *     System.out.println("Value update failed");
 * }
 * 
 * // 从现有数组创建
 * int[] initialValues = {1, 2, 3, 4, 5};
 * AtomicIntegerArray array2 = new AtomicIntegerArray(initialValues);
 * 
 * // 函数式更新(Java 8+)
 * int result = array2.updateAndGet(0, x -> x * 2);
 * int previous = array2.getAndUpdate(0, x -> x + 1);
 * 
 * // 累积操作(Java 8+)
 * int accumulated = array2.accumulateAndGet(0, 10, Integer::sum);
 * int previousAcc = array2.getAndAccumulate(0, 5, Math::max);
 * 
 * // 多线程计数器数组示例
 * class ThreadSafeCounterArray {
 *     private final AtomicIntegerArray counters;
 *     
 *     public ThreadSafeCounterArray(int size) {
 *         counters = new AtomicIntegerArray(size);
 *     }
 *     
 *     public void increment(int index) {
 *         counters.incrementAndGet(index);
 *     }
 *     
 *     public void decrement(int index) {
 *         counters.decrementAndGet(index);
 *     }
 *     
 *     public void add(int index, int delta) {
 *         counters.addAndGet(index, delta);
 *     }
 *     
 *     public int get(int index) {
 *         return counters.get(index);
 *     }
 *     
 *     public int size() {
 *         return counters.length();
 *     }
 *     
 *     public boolean compareAndSet(int index, int expect, int update) {
 *         return counters.compareAndSet(index, expect, update);
 *     }
 * }
 * 
 * // 状态标志数组示例
 * class StatusFlagArray {
 *     private final AtomicIntegerArray flags;
 *     
 *     public StatusFlagArray(int size) {
 *         flags = new AtomicIntegerArray(size);
 *     }
 *     
 *     public void setStatus(int index, boolean status) {
 *         flags.set(index, status ? 1 : 0);
 *     }
 *     
 *     public boolean getStatus(int index) {
 *         return flags.get(index) != 0;
 *     }
 *     
 *     public boolean trySetStatus(int index, boolean expected, boolean newValue) {
 *         int expect = expected ? 1 : 0;
 *         int update = newValue ? 1 : 0;
 *         return flags.compareAndSet(index, expect, update);
 *     }
 *     
 *     public void resetAll() {
 *         for (int i = 0; i < flags.length(); i++) {
 *             flags.set(i, 0);
 *         }
 *     }
 * }
 * 
 * // 统计信息收集示例
 * class StatisticsCollector {
 *     private final AtomicIntegerArray statistics;
 *     public static final int REQUEST_COUNT = 0;
 *     public static final int ERROR_COUNT = 1;
 *     public static final int SUCCESS_COUNT = 2;
 *     public static final int TOTAL_COUNT = 3;
 *     
 *     public StatisticsCollector() {
 *         statistics = new AtomicIntegerArray(4);
 *     }
 *     
 *     public void recordRequest() {
 *         statistics.incrementAndGet(REQUEST_COUNT);
 *     }
 *     
 *     public void recordError() {
 *         statistics.incrementAndGet(ERROR_COUNT);
 *     }
 *     
 *     public void recordSuccess() {
 *         statistics.incrementAndGet(SUCCESS_COUNT);
 *         statistics.incrementAndGet(TOTAL_COUNT);
 *     }
 *     
 *     public int getRequestCount() {
 *         return statistics.get(REQUEST_COUNT);
 *     }
 *     
 *     public int getErrorCount() {
 *         return statistics.get(ERROR_COUNT);
 *     }
 *     
 *     public int getSuccessCount() {
 *         return statistics.get(SUCCESS_COUNT);
 *     }
 *     
 *     public int getTotalCount() {
 *         return statistics.get(TOTAL_COUNT);
 *     }
 *     
 *     public void reset() {
 *         for (int i = 0; i < statistics.length(); i++) {
 *             statistics.set(i, 0);
 *         }
 *     }
 * }
 * 
 * 最佳实践:
 * 
 * 1. 正确使用原子操作:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 正确的做法:使用原子操作
 *    array.incrementAndGet(0);
 *    
 *    // 错误的做法:非原子操作
 *    // array.set(0, array.get(0) + 1); // 不是原子操作!
 * 
 * 2. 合理使用compareAndSet:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 正确使用:检查返回值
 *    public boolean tryUpdate(int index, int expected, int newValue) {
 *        return array.compareAndSet(index, expected, newValue);
 *    }
 *    
 *    // 错误使用:忽略返回值
 *    // array.compareAndSet(0, 0, 1); // 没有检查返回值
 * 
 * 3. 选择合适的获取方法:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 当需要旧值时使用getAnd系列方法
 *    int oldValue = array.getAndIncrement(0);
 *    System.out.println("Old value was: " + oldValue);
 *    
 *    // 当需要新值时使用incrementAndGet等方法
 *    int newValue = array.incrementAndGet(0);
 *    System.out.println("New value is: " + newValue);
 * 
 * 4. 处理CAS失败的情况:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 使用循环确保操作成功
 *    public boolean updateValue(int index, int expected, int newValue) {
 *        return array.compareAndSet(index, expected, newValue);
 *    }
 *    
 *    // 或者使用函数式方法
 *    public int doubleValue(int index) {
 *        return array.updateAndGet(index, x -> x * 2);
 *    }
 * 
 * 5. 避免ABA问题:
 *    // ABA问题示例:值从A变为B再变为A
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 线程1准备更新
 *    int expected = array.get(0); // 获取到10
 *    
 *    // 线程2执行:10 -> 20 -> 10
 *    array.compareAndSet(0, 10, 20);
 *    array.compareAndSet(0, 20, 10);
 *    
 *    // 线程1执行:CAS成功,但实际上中间状态发生了变化
 *    array.compareAndSet(0, expected, 30); // 成功,但可能不是期望的行为
 *    
 *    // 解决方案:使用版本号或时间戳
 *    class VersionedArray {
 *        private final AtomicIntegerArray values;
 *        private final AtomicIntegerArray versions;
 *        
 *        public VersionedArray(int size) {
 *            values = new AtomicIntegerArray(size);
 *            versions = new AtomicIntegerArray(size);
 *        }
 *        
 *        public boolean compareAndSet(int index, int expectedValue, 
 *                                   int expectedVersion, int newValue) {
 *            int currentVersion = versions.get(index);
 *            if (currentVersion != expectedVersion) {
 *                return false; // 版本不匹配
 *            }
 *            if (!values.compareAndSet(index, expectedValue, newValue)) {
 *                return false; // 值不匹配
 *            }
 *            versions.incrementAndGet(index); // 更新版本
 *            return true;
 *        }
 *    }
 * 
 * 6. 合理使用函数式更新:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 简单操作使用专门方法
 *    array.incrementAndGet(0); // 比函数式更快
 *    
 *    // 复杂操作使用函数式方法
 *    int result = array.updateAndGet(0, x -> {
 *        // 复杂计算
 *        return complexCalculation(x);
 *    });
 * 
 * 7. 边界检查:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 始终进行边界检查
 *    public void safeIncrement(int index) {
 *        if (index >= 0 && index < array.length()) {
 *            array.incrementAndGet(index);
 *        } else {
 *            throw new IndexOutOfBoundsException("Index out of bounds: " + index);
 *        }
 *    }
 *    
 *    // 或者让AtomicIntegerArray自动处理
 *    // array.incrementAndGet(10); // 会抛出IndexOutOfBoundsException
 * 
 * 8. 监控和调试:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 定期检查数组状态
 *    public void logArrayStatus() {
 *        System.out.println("Array contents: " + array.toString());
 *    }
 *    
 *    // 性能监控
 *    public void monitorPerformance() {
 *        long startTime = System.nanoTime();
 *        // 执行一些操作
 *        for (int i = 0; i < 1000000; i++) {
 *            array.incrementAndGet(i % array.length());
 *        }
 *        long endTime = System.nanoTime();
 *        System.out.println("Time taken: " + (endTime - startTime) + " ns");
 *    }
 * 
 * 9. 批量操作优化:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    // 避免频繁的原子操作
 *    // 错误做法:每次循环都进行原子操作
 *    // for (int i = 0; i < 1000; i++) {
 *    //     array.incrementAndGet(0);
 *    // }
 *    
 *    // 正确做法:批量更新(如果可能)
 *    // 对于数组元素,通常无法批量更新,但可以优化访问模式
 *    public void optimizedBatchUpdate() {
 *        // 尽量减少不必要的原子操作
 *        int currentValue = array.get(0);
 *        if (currentValue < 1000) {
 *            array.addAndGet(0, 1000 - currentValue);
 *        }
 *    }
 * 
 * 10. 异常处理:
 *    AtomicIntegerArray array = new AtomicIntegerArray(10);
 *    
 *    public void safeUpdate(int index, IntUnaryOperator updateFunction) {
 *        try {
 *            array.updateAndGet(index, updateFunction);
 *        } catch (IndexOutOfBoundsException e) {
 *            System.err.println("Index out of bounds: " + e.getMessage());
 *        } catch (Exception e) {
 *            System.err.println("Update failed: " + e.getMessage());
 *            // 记录日志或采取其他措施
 *        }
 *    }
 * 
 * 11. 性能调优:
 *    // 在高并发场景下监控性能
 *    AtomicIntegerArray array = new AtomicIntegerArray(1000);
 *    
 *    // 使用局部变量减少数组访问
 *    public void optimizedAccess(int index) {
 *        int localValue = array.get(index);
 *        if (localValue > 0) {
 *            // 执行相关逻辑
 *        }
 *    }
 *    
 *    // 避免不必要的原子操作
 *    public void conditionalOperation(int index) {
 *        if (array.get(index) > 0) { // 先检查
 *            // 再执行原子操作
 *            array.compareAndSet(index, array.get(index), 0);
 *        }
 *    }
 */

7. 与其他原子类的比较

/**
 * AtomicIntegerArray vs AtomicInteger vs AtomicReferenceArray vs 普通数组:
 * 
 * AtomicIntegerArray:
 * - 用于int数组的原子操作
 * - 每个元素支持独立的原子操作
 * - 提供丰富的数学运算方法
 * - 适用于需要原子操作的整数数组
 * 
 * AtomicInteger:
 * - 用于单个int值的原子操作
 * - 提供与AtomicIntegerArray类似的方法
 * - 适用于单个计数器或状态值
 * 
 * AtomicReferenceArray:
 * - 用于对象引用数组的原子操作
 * - 支持CAS操作对象引用
 * - 适用于复杂对象数组的原子操作
 * - 可以配合版本控制解决ABA问题
 * 
 * 普通数组:
 * - 非线程安全的数组操作
 * - 需要外部同步机制
 * - 性能最好(无同步开销)
 * - 适用于单线程环境
 * 
 * 性能对比:
 * - 基本操作:普通数组 > AtomicIntegerArray > AtomicInteger
 * - 线程安全:AtomicIntegerArray = AtomicInteger > 普通数组
 * - 内存使用:AtomicIntegerArray < AtomicInteger[] < 普通数组
 * - 功能丰富度:AtomicIntegerArray > 普通数组
 * 
 * 选择建议:
 * - 单个值:AtomicInteger
 * - 整数数组:AtomicIntegerArray
 * - 对象数组:AtomicReferenceArray
 * - 单线程:普通数组
 * - 需要版本控制:AtomicStampedReference
 * 
 * 使用场景:
 * - AtomicIntegerArray:计数器数组、状态数组、统计信息数组
 * - AtomicInteger:单个计数器、序列号、简单的数值操作
 * - AtomicReferenceArray:对象引用数组、缓存数组
 * - 普通数组:单线程数据处理、临时存储
 */

8. 总结

AtomicIntegerArray 的核心特性:

  1. 数组原子操作

    • 提供对数组元素的原子操作
    • 每个元素可以独立进行原子操作
    • 支持细粒度的并发控制
  2. 无锁原子操作

    • 使用CAS实现原子性
    • 避免传统锁的开销
    • 提供乐观锁机制
  3. 内存可见性

    • 通过Unsafe的volatile操作保证可见性
    • 确保多线程间的内存可见性
    • 确保读操作获取最新值
  4. 丰富的原子操作

    • 基本的get/set操作
    • 自增自减操作
    • 比较并设置操作
    • 函数式更新操作(Java 8+)
  5. 边界安全

    • 所有操作都进行索引边界检查
    • 防止数组越界异常
    • 提供安全的数组访问
  6. 高性能设计

    • 基于Unsafe的底层操作
    • 数组偏移量直接访问
    • 自旋重试机制
  7. 线程安全

    • 所有操作都是线程安全的
    • 适用于高并发环境
    • 无死锁风险

适用场景:

  • 多线程环境下的计数器数组
  • 状态标志数组
  • 需要原子操作的整数数组
  • 高并发环境下的数组操作
  • 需要细粒度并发控制的场景
  • 统计信息收集
  • 缓存系统中的计数数组

注意事项:

  • CAS操作可能出现ABA问题
  • 高竞争场景下可能有自旋开销
  • 不支持复合原子操作(需要多个步骤的原子操作)
  • 需要正确处理CAS的返回值
  • 注意选择合适的更新方法
  • 始终进行边界检查
  • 大数组可能占用较多内存

性能优化建议:

  1. 根据数据类型选择合适的原子数组类
  2. 合理使用compareAndSet避免不必要的操作
  3. 在高竞争场景下考虑减少竞争
  4. 监控原子操作的性能表现
  5. 避免频繁的原子操作
  6. 正确处理ABA问题(必要时使用版本控制)
  7. 选择合适的获取方法(getAnd系列 vs incrementAndGet系列)
  8. 使用局部变量减少数组访问
  9. 考虑使用更细粒度的并发控制
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值