AtomicArray详解
2025-06-28 16:20 halberts 阅读(26) 评论(0) 收藏 举报1.AtomicArray 详解
AtomicArray 是 Java 提供的一种线程安全工具类,用于处理多个元素的原子操作。常见实现包括:
AtomicIntegerArray:支持 int 类型数组的原子操作。
AtomicLongArray:支持 long 类型数组的原子操作。
AtomicReferenceArray:支持引用类型数组的原子操作。
这些类的设计基于无锁(lock-free)机制,通过底层的 CAS(Compare-And-Swap)操作,提供线程安全的操作而不需要显式加锁。
2. 主要特点
线程安全:每个元素的读写操作都是线程安全的,确保并发环境下数据的正确性。
高性能:基于 CAS 实现的原子操作,无需显式锁定,避免线程阻塞和上下文切换的开销。
无锁操作:避免了锁的使用,尤其在高并发环境下表现出色。
可操作多个元素:提供数组形式,支持对每个数组元素进行独立的原子性操作。
3. 主要实现类
1. AtomicIntegerArray
概述:用于对 int 类型数组的每个元素执行原子操作。
构造方法:
AtomicIntegerArray(int length):创建指定长度的数组,元素初始值为 0。
AtomicIntegerArray(int[] array):使用现有数组初始化,原数组会被拷贝。
常用方法:
get(int index):获取指定索引的值。
set(int index, int value):设置指定索引的值。
getAndSet(int index, int value):获取旧值并设置新值。
compareAndSet(int index, int expect, int update):CAS 操作。
getAndIncrement(int index):获取值并自增。
incrementAndGet(int index):自增并获取值。
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayExample {
public static void main(String[] args) {
AtomicIntegerArray atomicArray = new AtomicIntegerArray(5);
// 初始化值
atomicArray.set(0, 10);
// 自增操作
int oldValue = atomicArray.getAndIncrement(0);
System.out.println("Old Value: " + oldValue); // 输出: 10
System.out.println("New Value: " + atomicArray.get(0)); // 输出: 11
// CAS 操作
boolean updated = atomicArray.compareAndSet(0, 11, 20);
System.out.println("Update Successful: " + updated); // 输出: true
System.out.println("Updated Value: " + atomicArray.get(0)); // 输出: 20
}
}
2. AtomicLongArray
概述:用于对 long 类型数组的每个元素执行原子操作。
构造方法:
AtomicLongArray(int length):创建指定长度的数组,元素初始值为 0。
AtomicLongArray(long[] array):使用现有数组初始化,原数组会被拷贝。
常用方法:
与 AtomicIntegerArray 类似,方法针对 long 类型。
import java.util.concurrent.atomic.AtomicLongArray;
public class AtomicLongArrayExample {
public static void main(String[] args) {
AtomicLongArray atomicArray = new AtomicLongArray(new long[] {10L, 20L, 30L});
// 自减操作
long oldValue = atomicArray.getAndDecrement(1);
System.out.println("Old Value: " + oldValue); // 输出: 20
System.out.println("New Value: " + atomicArray.get(1)); // 输出: 19
// CAS 操作
boolean updated = atomicArray.compareAndSet(1, 19, 25);
System.out.println("Update Successful: " + updated); // 输出: true
System.out.println("Updated Value: " + atomicArray.get(1)); // 输出: 25
}
}
3. AtomicReferenceArray
概述:支持对引用类型数组的原子操作。
构造方法:
AtomicReferenceArray(int length):创建指定长度的数组,元素初始值为 null。
AtomicReferenceArray(E[] array):使用现有数组初始化,原数组会被拷贝。
常用方法:
get(int index):获取指定索引的引用。
set(int index, E value):设置指定索引的引用。
compareAndSet(int index, E expect, E update):CAS 操作。
getAndSet(int index, E newValue):获取旧值并设置新值。
import java.util.concurrent.atomic.AtomicReferenceArray;
public class AtomicReferenceArrayExample {
public static void main(String[] args) {
AtomicReferenceArray<String> atomicArray = new AtomicReferenceArray<>(3);
// 设置值
atomicArray.set(0, "A");
atomicArray.set(1, "B");
// CAS 操作
boolean updated = atomicArray.compareAndSet(1, "B", "C");
System.out.println("Update Successful: " + updated); // 输出: true
System.out.println("Updated Value: " + atomicArray.get(1)); // 输出: C
}
}
4. AtomicArray 的性能表现
优点:
基于 CAS 的原子操作,性能高于显式加锁。
避免了锁竞争问题,尤其适用于读多写少的场景。
缺点:
在高冲突情况下,CAS 操作可能多次重试,导致忙等待。
不能解决复杂场景下的并发问题,例如多个元素间的原子性操作。
适用场景:
多线程环境下,对数组中单个元素进行高频更新的场景。
对数组中的数据需要保证线程安全,但不需要操作多个元素之间的原子性。
注意事项
数据初始化:构造方法会拷贝原始数组,原数组的修改不会影响 AtomicArray。
ABA 问题:和其他基于 CAS 的工具类似,AtomicArray 也存在 ABA 问题。如果需要解决,使用带版本号的方案。
大数组性能:在处理大数组时,AtomicArray 的每次操作需要访问主存,相较于本地缓存数组性能稍逊。
5.总结
AtomicArray 提供了线程安全的数组操作,适合在并发环境中对单个数组元素执行原子操作。
实现方式基于 CAS,性能较高,但适合高并发读写少量冲突的场景。
常见实现包括 AtomicIntegerArray、AtomicLongArray 和 AtomicReferenceArray,分别支持整型、长整型和引用类型数据。
在实际开发中,AtomicArray 常用于计数器、状态记录器等需要线程安全的数组数据场景。
浙公网安备 33010602011771号