public class AtomicLongArray implements java.io.Serializable {
// 序列化版本号
private static final long serialVersionUID = -2308431214976778248L;
/**
* Unsafe类实例,提供底层的原子操作
* 通过Unsafe可以直接操作内存地址,实现CAS等原子操作
*/
private static final sun.misc.Unsafe unsafe = getUnsafe();
/**
* 数组的第一个元素在内存中的偏移量
* 用于计算数组元素的内存地址
*/
private static final int base = unsafe.arrayBaseOffset(long[].class);
/**
* 数组元素之间的地址增量(步长)
* 用于计算数组中任意元素的内存地址
*/
private static final int shift;
/**
* 静态初始化块,计算shift值
* 根据数组元素的地址增量确定位移量
*/
static {
int scale = unsafe.arrayIndexScale(long[].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());
}
}
}
/**
* 实际存储的long数组
* 使用volatile修饰确保内存可见性
* 所有原子操作都是针对这个数组进行的
*/
private final long[] array;
/**
* 构造方法,创建指定长度的AtomicLongArray
* @param length 数组长度
*
* 初始化过程:
* 1. 创建指定长度的long数组
* 2. 数组元素初始化为0(long的默认值)
* 3. volatile语义确保对其他线程的可见性
*
* @throws NegativeArraySizeException 如果length为负数
*/
public AtomicLongArray(int length) {
array = new long[length];
}
/**
* 构造方法,从给定数组创建AtomicLongArray
* @param array 给定的long数组
*
* 初始化过程:
* 1. 复制给定数组的内容
* 2. 创建新的long数组存储副本
* 3. volatile语义确保对其他线程的可见性
*
* @throws NullPointerException 如果array为null
*/
public AtomicLongArray(long[] 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 long get(int i) {
return getRaw(checkedByteOffset(i));
}
/**
* 设置指定索引位置的值
* 这个操作不是原子的,只是简单地设置新值
*
* 注意事项:
* - 这个方法不保证原子性
* - 如果需要原子性设置,应该使用compareAndSet方法
* - volatile语义确保新值对其他线程可见
*
* @param i 索引位置
* @param newValue 新值
* @throws IndexOutOfBoundsException 如果索引越界
*/
public final void set(int i, long newValue) {
unsafe.putLongVolatile(array, checkedByteOffset(i), newValue);
}
/**
* 最终设置指定索引位置的值
* 这个方法确保在方法返回之前,新值对其他线程可见
*
* 与set方法的区别:
* - lazySet可能延迟设置,提高性能
* - setImmediately确保立即设置
*
* @param i 索引位置
* @param newValue 新值
* @throws IndexOutOfBoundsException 如果索引越界
*/
public final void lazySet(int i, long newValue) {
unsafe.putOrderedLong(array, checkedByteOffset(i), newValue);
}
/**
* 原子地设置指定索引位置的值并返回旧值
* 这是一个原子操作,保证读取和设置的原子性
*
* 操作过程:
* 1. 读取指定位置的当前值
* 2. 设置新值
* 3. 返回旧值
*
* 时间复杂度:O(1)
* 线程安全性:完全原子性
*
* @param i 索引位置
* @param newValue 新值
* @return 旧值
* @throws IndexOutOfBoundsException 如果索引越界
*/
public final long getAndSet(int i, long newValue) {
return unsafe.getAndSetLong(array, 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, long expect, long update) {
return unsafe.compareAndSwapLong(array, checkedByteOffset(i), expect, update);
}
/**
* 弱原子地比较并设置指定索引位置的值
* 与compareAndSet类似,但在某些平台上可能不提供完全的内存排序保证
*
* 使用场景:
* - 对内存排序要求不严格的场景
* - 性能要求极高的场景
*
* @param i 索引位置
* @param expect 期望值
* @param update 新值
* @return 如果设置成功返回true,否则返回false
* @throws IndexOutOfBoundsException 如果索引越界
*/
public final boolean weakCompareAndSet(int i, long expect, long update) {
return unsafe.compareAndSwapLong(array, checkedByteOffset(i), expect, update);
}
/**
* 原子地增加1并返回旧值
* 这是一个原子的自增操作
*
* 操作过程:
* 1. 获取指定位置的当前值
* 2. 计算新值(当前值+1)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回旧值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param i 索引位置
* @return 增加前的值
* @throws IndexOutOfBoundsException 如果索引越界
*/
public final long getAndIncrement(int i) {
return getAndAdd(i, 1L);
}
/**
* 原子地减少1并返回旧值
* 这是一个原子的自减操作
*
* 操作过程:
* 1. 获取指定位置的当前值
* 2. 计算新值(当前值-1)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回旧值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param i 索引位置
* @return 减少前的值
* @throws IndexOutOfBoundsException 如果索引越界
*/
public final long getAndDecrement(int i) {
return getAndAdd(i, -1L);
}
/**
* 原子地增加指定值并返回旧值
* 这是一个原子的加法操作
*
* 操作过程:
* 1. 获取指定位置的当前值
* 2. 计算新值(当前值+delta)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回旧值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param i 索引位置
* @param delta 要增加的值
* @return 增加前的值
* @throws IndexOutOfBoundsException 如果索引越界
*/
public final long getAndAdd(int i, long delta) {
return unsafe.getAndAddLong(array, 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 long incrementAndGet(int i) {
return addAndGet(i, 1L);
}
/**
* 原子地减少1并返回新值
* 这是一个原子的自减操作
*
* 与getAndDecrement的区别:
* - getAndDecrement返回旧值
* - decrementAndGet返回新值
*
* 操作过程:
* 1. 获取指定位置的当前值
* 2. 计算新值(当前值-1)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回新值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param i 索引位置
* @return 减少后的值
* @throws IndexOutOfBoundsException 如果索引越界
*/
public final long decrementAndGet(int i) {
return addAndGet(i, -1L);
}
/**
* 原子地增加指定值并返回新值
* 这是一个原子的加法操作
*
* 与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 long addAndGet(int i, long delta) {
return unsafe.getAndAddLong(array, 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 long updateAndGet(int i, LongUnaryOperator updateFunction) {
long offset = checkedByteOffset(i);
long prev, next;
do {
prev = getRaw(offset);
next = updateFunction.applyAsLong(prev);
} while (!compareAndSet(i, 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 long getAndUpdate(int i, LongUnaryOperator updateFunction) {
long offset = checkedByteOffset(i);
long prev, next;
do {
prev = getRaw(offset);
next = updateFunction.applyAsLong(prev);
} while (!compareAndSet(i, 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 long accumulateAndGet(int i, long x,
LongBinaryOperator accumulatorFunction) {
long offset = checkedByteOffset(i);
long prev, next;
do {
prev = getRaw(offset);
next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSet(i, 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 long getAndAccumulate(int i, long x,
LongBinaryOperator accumulatorFunction) {
long offset = checkedByteOffset(i);
long prev, next;
do {
prev = getRaw(offset);
next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSet(i, prev, next));
return prev;
}
/**
* 检查数组索引并计算字节偏移量
* 确保索引在有效范围内,并计算对应的内存偏移量
*
* @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 long getRaw(long offset) {
return unsafe.getLongVolatile(array, offset);
}
/**
* 返回对象的字符串表示
* 重写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++) {
long element = get(i);
int elementHash = (int)(element ^ (element >>> 32));
result = 31 * result + elementHash;
}
return result;
}
/**
* 比较两个AtomicLongArray对象是否相等
* 重写Object类的equals方法
*
* @param obj 要比较的对象
* @return 如果相等返回true,否则返回false
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof AtomicLongArray))
return false;
AtomicLongArray that = (AtomicLongArray) 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;
}
/**
* AtomicLongArray的核心设计思想:
*
* 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. 边界检查:
* - 所有操作都进行索引边界检查
* - 防止数组越界异常
* - 提供安全的数组访问
*
* 9. 64位精度:
* - 支持long类型的64位操作
* - 适用于需要大数值范围的场景
* - 在32位系统上需要特殊处理
*
* 适用场景:
* - 多线程环境下的大数值计数器数组
* - 时间戳数组
* - 需要原子操作的长整数数组
* - 高并发环境下的数组操作
* - 需要细粒度并发控制的场景
*/
/**
* AtomicLongArray的性能特征:
*
* 时间复杂度:
* - 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个long值
* - 每个元素都有固定的内存开销
*
* 并发特性:
* - 完全线程安全
* - 每个数组元素可以独立进行原子操作
* - 无锁设计,避免线程阻塞
* - 乐观锁机制,适用于低竞争场景
* - 高竞争场景下可能出现自旋开销
*
* 与synchronized数组对比:
* - 无竞争:AtomicLongArray > synchronized数组
* - 低竞争:AtomicLongArray > synchronized数组
* - 高竞争:AtomicLongArray可能 < synchronized数组
* - 内存开销:AtomicLongArray < synchronized数组
*
* 与AtomicLong[]对比:
* - 功能相似:都提供原子操作
* - 内存使用:AtomicLongArray < AtomicLong[]
* - 性能:AtomicLongArray ≥ AtomicLong[]
* - 管理复杂度:AtomicLongArray < AtomicLong[]
*
* 与AtomicIntegerArray对比:
* - 功能相似:都提供原子操作
* - 数值范围:AtomicLongArray > AtomicIntegerArray
* - 性能:AtomicIntegerArray > AtomicLongArray
* - 内存使用:AtomicLongArray > AtomicIntegerArray
*
* CAS操作特点:
* - 乐观锁:假设没有冲突,冲突时重试
* - 非阻塞:不会阻塞其他线程
* - ABA问题:需要额外机制解决
* - 自旋开销:高竞争时CPU使用率可能较高
*
* 内存使用:
* - 每个实例存储一个数组引用
* - 数组元素通过volatile保证可见性
* - 及时GC,避免内存泄漏
*
* 适用性:
* - 数组元素原子操作:性能优异
* - 高频数组更新场景:性能优异
* - 复杂同步逻辑:可能不如锁机制
* - 需要精确控制:比锁更灵活
*/
/**
* 使用示例:
*
* // 基本使用
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 原子设置和获取
* array.set(0, 100L);
* long value = array.get(0);
*
* // 原子自增
* long oldValue = array.getAndIncrement(0); // 返回旧值
* long newValue = array.incrementAndGet(0); // 返回新值
*
* // 原子自减
* long oldValue2 = array.getAndDecrement(0);
* long newValue2 = array.decrementAndGet(0);
*
* // 原子加法
* long oldValue3 = array.getAndAdd(0, 5L);
* long newValue3 = array.addAndGet(0, 5L);
*
* // 比较并设置
* boolean success = array.compareAndSet(0, 10L, 20L);
* if (success) {
* System.out.println("Value updated successfully");
* } else {
* System.out.println("Value update failed");
* }
*
* // 从现有数组创建
* long[] initialValues = {1L, 2L, 3L, 4L, 5L};
* AtomicLongArray array2 = new AtomicLongArray(initialValues);
*
* // 函数式更新(Java 8+)
* long result = array2.updateAndGet(0, x -> x * 2L);
* long previous = array2.getAndUpdate(0, x -> x + 1L);
*
* // 累积操作(Java 8+)
* long accumulated = array2.accumulateAndGet(0, 10L, Long::sum);
* long previousAcc = array2.getAndAccumulate(0, 5L, Math::max);
*
* // 时间戳数组示例
* class TimestampArray {
* private final AtomicLongArray timestamps;
*
* public TimestampArray(int size) {
* timestamps = new AtomicLongArray(size);
* }
*
* public long getNextTimestamp(int index) {
* long current, next;
* do {
* current = timestamps.get(index);
* next = System.currentTimeMillis();
* // 确保时间戳单调递增
* if (next <= current) {
* next = current + 1;
* }
* } while (!timestamps.compareAndSet(index, current, next));
* return next;
* }
*
* public long getTimestamp(int index) {
* return timestamps.get(index);
* }
*
* public void resetTimestamp(int index) {
* timestamps.set(index, 0L);
* }
* }
*
* // 大数值计数器数组示例
* class LargeCounterArray {
* private final AtomicLongArray counters;
*
* public LargeCounterArray(int size) {
* counters = new AtomicLongArray(size);
* }
*
* public void increment(int index) {
* counters.incrementAndGet(index);
* }
*
* public void add(int index, long delta) {
* counters.addAndGet(index, delta);
* }
*
* public long get(int index) {
* return counters.get(index);
* }
*
* public long size() {
* return counters.length();
* }
*
* public boolean compareAndSet(int index, long expect, long update) {
* return counters.compareAndSet(index, expect, update);
* }
*
* // 处理可能的溢出
* public long getAndReset(int index) {
* return counters.getAndSet(index, 0L);
* }
* }
*
* // 序列号生成器数组示例
* class SequenceGeneratorArray {
* private final AtomicLongArray sequences;
*
* public SequenceGeneratorArray(int size) {
* sequences = new AtomicLongArray(size);
* }
*
* public long getNextSequence(int index) {
* return sequences.incrementAndGet(index);
* }
*
* public long getCurrentSequence(int index) {
* return sequences.get(index);
* }
*
* public void resetSequence(int index, long newValue) {
* sequences.set(index, newValue);
* }
*
* // 支持批量获取序列号
* public long[] getNextSequences(int index, int count) {
* long start = sequences.getAndAdd(index, count);
* long[] sequences = new long[count];
* for (int i = 0; i < count; i++) {
* sequences[i] = start + i;
* }
* return sequences;
* }
* }
*
* // 统计信息收集示例
* class StatisticsCollector {
* private final AtomicLongArray 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 static final int PROCESSING_TIME = 4;
*
* public StatisticsCollector() {
* statistics = new AtomicLongArray(5);
* }
*
* public void recordRequest() {
* statistics.incrementAndGet(REQUEST_COUNT);
* }
*
* public void recordError() {
* statistics.incrementAndGet(ERROR_COUNT);
* }
*
* public void recordSuccess(long processingTime) {
* statistics.incrementAndGet(SUCCESS_COUNT);
* statistics.incrementAndGet(TOTAL_COUNT);
* statistics.addAndGet(PROCESSING_TIME, processingTime);
* }
*
* public long getRequestCount() {
* return statistics.get(REQUEST_COUNT);
* }
*
* public long getErrorCount() {
* return statistics.get(ERROR_COUNT);
* }
*
* public long getSuccessCount() {
* return statistics.get(SUCCESS_COUNT);
* }
*
* public long getTotalCount() {
* return statistics.get(TOTAL_COUNT);
* }
*
* public long getProcessingTime() {
* return statistics.get(PROCESSING_TIME);
* }
*
* public double getAverageProcessingTime() {
* long successCount = getSuccessCount();
* long totalTime = getProcessingTime();
* return successCount > 0 ? (double) totalTime / successCount : 0.0;
* }
*
* public void reset() {
* for (int i = 0; i < statistics.length(); i++) {
* statistics.set(i, 0L);
* }
* }
* }
*
* 最佳实践:
*
* 1. 正确使用原子操作:
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 正确的做法:使用原子操作
* array.incrementAndGet(0);
*
* // 错误的做法:非原子操作
* // array.set(0, array.get(0) + 1L); // 不是原子操作!
*
* 2. 合理使用compareAndSet:
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 正确使用:检查返回值
* public boolean tryUpdate(int index, long expected, long newValue) {
* return array.compareAndSet(index, expected, newValue);
* }
*
* // 错误使用:忽略返回值
* // array.compareAndSet(0, 0L, 1L); // 没有检查返回值
*
* 3. 选择合适的获取方法:
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 当需要旧值时使用getAnd系列方法
* long oldValue = array.getAndIncrement(0);
* System.out.println("Old value was: " + oldValue);
*
* // 当需要新值时使用incrementAndGet等方法
* long newValue = array.incrementAndGet(0);
* System.out.println("New value is: " + newValue);
*
* 4. 处理CAS失败的情况:
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 使用循环确保操作成功
* public boolean updateValue(int index, long expected, long newValue) {
* return array.compareAndSet(index, expected, newValue);
* }
*
* // 或者使用函数式方法
* public long doubleValue(int index) {
* return array.updateAndGet(index, x -> x * 2L);
* }
*
* 5. 避免ABA问题:
* // ABA问题示例:值从A变为B再变为A
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 线程1准备更新
* long expected = array.get(0); // 获取到10
*
* // 线程2执行:10 -> 20 -> 10
* array.compareAndSet(0, 10L, 20L);
* array.compareAndSet(0, 20L, 10L);
*
* // 线程1执行:CAS成功,但实际上中间状态发生了变化
* array.compareAndSet(0, expected, 30L); // 成功,但可能不是期望的行为
*
* // 解决方案:使用版本号或时间戳
* class VersionedLongArray {
* private final AtomicLongArray values;
* private final AtomicIntegerArray versions;
*
* public VersionedLongArray(int size) {
* values = new AtomicLongArray(size);
* versions = new AtomicIntegerArray(size);
* }
*
* public boolean compareAndSet(int index, long expectedValue,
* int expectedVersion, long 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. 合理使用函数式更新:
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 简单操作使用专门方法
* array.incrementAndGet(0); // 比函数式更快
*
* // 复杂操作使用函数式方法
* long result = array.updateAndGet(0, x -> {
* // 复杂计算
* return complexCalculation(x);
* });
*
* 7. 处理溢出问题:
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 注意可能的溢出
* public void safeIncrement(int index) {
* long current = array.get(index);
* if (current < Long.MAX_VALUE) {
* array.incrementAndGet(index);
* } else {
* // 处理溢出情况
* System.err.println("Counter overflow detected at index " + index);
* }
* }
*
* // 或者使用饱和算术
* public long getAndIncrementSaturated(int index) {
* long current, next;
* do {
* current = array.get(index);
* if (current == Long.MAX_VALUE) {
* return current; // 饱和,不再增加
* }
* next = current + 1;
* } while (!array.compareAndSet(index, current, next));
* return current;
* }
*
* 8. 边界检查:
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 始终进行边界检查
* public void safeIncrement(int index) {
* if (index >= 0 && index < array.length()) {
* array.incrementAndGet(index);
* } else {
* throw new IndexOutOfBoundsException("Index out of bounds: " + index);
* }
* }
*
* // 或者让AtomicLongArray自动处理
* // array.incrementAndGet(10); // 会抛出IndexOutOfBoundsException
*
* 9. 监控和调试:
* AtomicLongArray array = new AtomicLongArray(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");
* }
*
* 10. 批量操作优化:
* AtomicLongArray array = new AtomicLongArray(10);
*
* // 避免频繁的原子操作
* // 错误做法:每次循环都进行原子操作
* // for (int i = 0; i < 1000; i++) {
* // array.incrementAndGet(0);
* // }
*
* // 正确做法:批量更新(如果可能)
* // 对于数组元素,通常无法批量更新,但可以优化访问模式
* public void optimizedBatchUpdate(int index) {
* // 尽量减少不必要的原子操作
* long currentValue = array.get(index);
* if (currentValue < 1000L) {
* array.addAndGet(index, 1000L - currentValue);
* }
* }
*
* 11. 异常处理:
* AtomicLongArray array = new AtomicLongArray(10);
*
* public void safeUpdate(int index, LongUnaryOperator 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());
* // 记录日志或采取其他措施
* }
* }
*
* 12. 性能调优:
* // 在高并发场景下监控性能
* AtomicLongArray array = new AtomicLongArray(1000);
*
* // 使用局部变量减少数组访问
* public void optimizedAccess(int index) {
* long localValue = array.get(index);
* if (localValue > 0L) {
* // 执行相关逻辑
* }
* }
*
* // 避免不必要的原子操作
* public void conditionalOperation(int index) {
* if (array.get(index) > 0L) { // 先检查
* // 再执行原子操作
* array.compareAndSet(index, array.get(index), 0L);
* }
* }
*/
/**
* AtomicLongArray vs AtomicIntegerArray vs AtomicReferenceArray vs 普通数组:
*
* AtomicLongArray:
* - 用于long数组的原子操作
* - 每个元素支持独立的原子操作
* - 提供丰富的数学运算方法
* - 64位精度,适用于大数值范围
*
* AtomicIntegerArray:
* - 用于int数组的原子操作
* - 每个元素支持独立的原子操作
* - 提供丰富的数学运算方法
* - 32位精度,性能略优于AtomicLongArray
*
* AtomicReferenceArray:
* - 用于对象引用数组的原子操作
* - 支持CAS操作对象引用
* - 适用于复杂对象数组的原子操作
* - 可以配合版本控制解决ABA问题
*
* 普通数组:
* - 非线程安全的数组操作
* - 需要外部同步机制
* - 性能最好(无同步开销)
* - 适用于单线程环境
*
* 性能对比:
* - 基本操作:普通数组 > AtomicIntegerArray > AtomicLongArray > AtomicReferenceArray
* - 线程安全:AtomicLongArray = AtomicIntegerArray = AtomicReferenceArray > 普通数组
* - 内存使用:AtomicLongArray < AtomicLong[] < 普通数组
* - 功能丰富度:AtomicLongArray > 普通数组
*
* 选择建议:
* - 单个值:AtomicLong
* - 整数数组:AtomicIntegerArray
* - 大数值数组:AtomicLongArray
* - 对象数组:AtomicReferenceArray
* - 单线程:普通数组
* - 需要版本控制:AtomicStampedReference
*
* 使用场景:
* - AtomicLongArray:时间戳数组、大数值计数器数组、统计信息数组
* - AtomicIntegerArray:计数器数组、状态数组、统计信息数组
* - AtomicReferenceArray:对象引用数组、缓存数组
* - 普通数组:单线程数据处理、临时存储
*/
数组原子操作:
无锁原子操作:
内存可见性:
丰富的原子操作:
64位精度支持:
边界安全:
高性能设计:
线程安全: