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. 考虑使用更细粒度的并发控制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值