JDK 8 AtomicLong 源码详解(详细注释版)
1. 类定义和基本属性
public class AtomicLong extends Number implements java.io.Serializable {
// 序列化版本号
private static final long serialVersionUID = 1927816293512124184L;
/**
* Unsafe类实例,提供底层的原子操作
* 通过Unsafe可以直接操作内存地址,实现CAS等原子操作
*/
private static final sun.misc.Unsafe unsafe = getUnsafe();
/**
* value字段在对象中的偏移量
* 通过这个偏移量可以使用Unsafe直接操作value字段的内存地址
* 这是实现原子操作的关键
*/
private static final long valueOffset;
/**
* 静态初始化块,获取value字段的偏移量
* 在类加载时执行,确保偏移量的正确性
*/
static {
try {
// 获取value字段的偏移量
valueOffset = unsafe.objectFieldOffset
(AtomicLong.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
/**
* 获取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 volatile long value;
/**
* 默认构造方法
* 创建一个初始值为0的AtomicLong
*
* 初始化过程:
* 1. value字段被初始化为0(long的默认值)
* 2. volatile语义确保对其他线程的可见性
*/
public AtomicLong() {
}
/**
* 指定初始值的构造方法
* @param initialValue 初始值
*
* 初始化过程:
* 1. value字段被设置为指定的初始值
* 2. volatile语义确保对其他线程的可见性
*/
public AtomicLong(long initialValue) {
value = initialValue;
}
/**
* 获取当前值
* 由于value字段是volatile的,这个方法保证返回最新的值
*
* 时间复杂度:O(1)
* 线程安全性:完全线程安全
*
* @return 当前值
*/
public final long get() {
return value;
}
/**
* 设置新值
* 这个操作不是原子的,只是简单地设置新值
*
* 注意事项:
* - 这个方法不保证原子性
* - 如果需要原子性设置,应该使用compareAndSet方法
* - volatile语义确保新值对其他线程可见
*
* @param newValue 新值
*/
public final void set(long newValue) {
value = newValue;
}
/**
* 最终设置新值
* 这个方法确保在方法返回之前,新值对其他线程可见
*
* 与set方法的区别:
* - lazySet可能延迟设置,提高性能
* - setImmediately确保立即设置
*
* @param newValue 新值
*/
public final void lazySet(long newValue) {
unsafe.putOrderedLong(this, valueOffset, newValue);
}
/**
* 原子地设置新值并返回旧值
* 这是一个原子操作,保证读取和设置的原子性
*
* 操作过程:
* 1. 读取当前值
* 2. 设置新值
* 3. 返回旧值
*
* 时间复杂度:O(1)
* 线程安全性:完全原子性
*
* @param newValue 新值
* @return 旧值
*/
public final long getAndSet(long newValue) {
return unsafe.getAndSetLong(this, valueOffset, newValue);
}
/**
* 原子地比较并设置值
* 只有当当前值等于期望值时,才设置为新值
*
* 操作过程:
* 1. 比较当前值和期望值
* 2. 如果相等,将当前值设置为新值
* 3. 返回比较结果
*
* CAS操作特点:
* - 无锁操作,性能优秀
* - 乐观锁机制,避免阻塞
* - 可能出现ABA问题
*
* 时间复杂度:O(1)
* 线程安全性:完全原子性
*
* @param expect 期望值
* @param update 新值
* @return 如果设置成功返回true,否则返回false
*/
public final boolean compareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
/**
* 弱原子地比较并设置值
* 与compareAndSet类似,但在某些平台上可能不提供完全的内存排序保证
*
* 使用场景:
* - 对内存排序要求不严格的场景
* - 性能要求极高的场景
*
* @param expect 期望值
* @param update 新值
* @return 如果设置成功返回true,否则返回false
*/
public final boolean weakCompareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
2. 原子更新方法(详细注释)
/**
* 原子地增加1并返回旧值
* 这是一个原子的自增操作
*
* 操作过程:
* 1. 获取当前值
* 2. 计算新值(当前值+1)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回旧值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @return 增加前的值
*/
public final long getAndIncrement() {
return unsafe.getAndAddLong(this, valueOffset, 1L);
}
/**
* 原子地减少1并返回旧值
* 这是一个原子的自减操作
*
* 操作过程:
* 1. 获取当前值
* 2. 计算新值(当前值-1)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回旧值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @return 减少前的值
*/
public final long getAndDecrement() {
return unsafe.getAndAddLong(this, valueOffset, -1L);
}
/**
* 原子地增加指定值并返回旧值
* 这是一个原子的加法操作
*
* 操作过程:
* 1. 获取当前值
* 2. 计算新值(当前值+delta)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回旧值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param delta 要增加的值
* @return 增加前的值
*/
public final long getAndAdd(long delta) {
return unsafe.getAndAddLong(this, valueOffset, delta);
}
/**
* 原子地增加1并返回新值
* 这是一个原子的自增操作
*
* 与getAndIncrement的区别:
* - getAndIncrement返回旧值
* - incrementAndGet返回新值
*
* 操作过程:
* 1. 获取当前值
* 2. 计算新值(当前值+1)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回新值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @return 增加后的值
*/
public final long incrementAndGet() {
return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
}
/**
* 原子地减少1并返回新值
* 这是一个原子的自减操作
*
* 与getAndDecrement的区别:
* - getAndDecrement返回旧值
* - decrementAndGet返回新值
*
* 操作过程:
* 1. 获取当前值
* 2. 计算新值(当前值-1)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回新值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @return 减少后的值
*/
public final long decrementAndGet() {
return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L;
}
/**
* 原子地增加指定值并返回新值
* 这是一个原子的加法操作
*
* 与getAndAdd的区别:
* - getAndAdd返回旧值
* - addAndGet返回新值
*
* 操作过程:
* 1. 获取当前值
* 2. 计算新值(当前值+delta)
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回新值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param delta 要增加的值
* @return 增加后的值
*/
public final long addAndGet(long delta) {
return unsafe.getAndAddLong(this, valueOffset, delta) + delta;
}
/**
* 原子地更新值,使用指定的更新函数
* 这是Java 8新增的方法,支持函数式编程
*
* 操作过程:
* 1. 获取当前值
* 2. 使用updateFunction计算新值
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回新值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param updateFunction 更新函数
* @return 更新后的值
*/
public final long updateAndGet(LongUnaryOperator updateFunction) {
long prev, next;
do {
prev = get();
next = updateFunction.applyAsLong(prev);
} while (!compareAndSet(prev, next));
return next;
}
/**
* 原子地更新值,使用指定的更新函数
* 返回更新前的值
*
* 操作过程:
* 1. 获取当前值
* 2. 使用updateFunction计算新值
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回旧值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param updateFunction 更新函数
* @return 更新前的值
*/
public final long getAndUpdate(LongUnaryOperator updateFunction) {
long prev, next;
do {
prev = get();
next = updateFunction.applyAsLong(prev);
} while (!compareAndSet(prev, next));
return prev;
}
/**
* 原子地累积值,使用指定的累积函数
* 这是Java 8新增的方法,支持累积操作
*
* 操作过程:
* 1. 获取当前值
* 2. 使用accumulatorFunction计算累积值
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回新值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param x 要累积的值
* @param accumulatorFunction 累积函数
* @return 累积后的值
*/
public final long accumulateAndGet(long x,
LongBinaryOperator accumulatorFunction) {
long prev, next;
do {
prev = get();
next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSet(prev, next));
return next;
}
/**
* 原子地累积值,使用指定的累积函数
* 返回累积前的值
*
* 操作过程:
* 1. 获取当前值
* 2. 使用accumulatorFunction计算累积值
* 3. 使用CAS操作更新值
* 4. 如果CAS失败,重复步骤1-3
* 5. 返回旧值
*
* 时间复杂度:O(1) 平均情况,O(∞) 最坏情况(高竞争)
* 线程安全性:完全原子性
*
* @param x 要累积的值
* @param accumulatorFunction 累积函数
* @return 累积前的值
*/
public final long getAndAccumulate(long x,
LongBinaryOperator accumulatorFunction) {
long prev, next;
do {
prev = get();
next = accumulatorFunction.applyAsLong(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}
3. Number类方法实现(详细注释)
/**
* 以int形式返回值
* 继承自Number类,用于类型转换
*
* @return int值
*/
public int intValue() {
return (int)get();
}
/**
* 以long形式返回值
* 继承自Number类,用于类型转换
*
* @return long值
*/
public long longValue() {
return get();
}
/**
* 以float形式返回值
* 继承自Number类,用于类型转换
*
* @return float值
*/
public float floatValue() {
return (float)get();
}
/**
* 以double形式返回值
* 继承自Number类,用于类型转换
*
* @return double值
*/
public double doubleValue() {
return (double)get();
}
4. 字符串表示方法(详细注释)
/**
* 返回对象的字符串表示
* 重写Object类的toString方法
*
* @return 当前值的字符串表示
*/
public String toString() {
return Long.toString(get());
}
/**
* 计算当前值的哈希码
* 重写Object类的hashCode方法
*
* @return 当前值的哈希码
*/
public int hashCode() {
long v = get();
return (int)(v ^ (v >>> 32));
}
/**
* 比较两个AtomicLong对象是否相等
* 重写Object类的equals方法
*
* @param obj 要比较的对象
* @return 如果相等返回true,否则返回false
*/
public boolean equals(Object obj) {
if (obj instanceof AtomicLong) {
return value == ((AtomicLong)obj).value;
}
return false;
}
5. AtomicLong 的特点分析
核心设计理念:
/**
* AtomicLong的核心设计思想:
*
* 1. 无锁编程:
* - 使用CAS(Compare-And-Swap)操作实现原子性
* - 避免传统锁的开销和阻塞
* - 提供乐观锁机制
*
* 2. volatile语义:
* - value字段使用volatile修饰
* - 保证内存可见性
* - 确保读操作获取最新值
*
* 3. Unsafe支持:
* - 使用sun.misc.Unsafe类提供底层原子操作
* - 直接操作内存地址,性能优异
* - 绕过JVM的常规访问控制
*
* 4. 偏移量机制:
* - 通过字段偏移量直接访问内存
* - 避免反射开销
* - 提供精确的内存操作
*
* 5. 自旋重试:
* - CAS失败时自动重试
* - 保证操作的最终成功
* - 适用于竞争不激烈的场景
*
* 6. 函数式支持:
* - Java 8新增函数式更新方法
* - 支持lambda表达式
* - 提供更灵活的原子操作
*
* 7. 64位精度:
* - 支持long类型的64位操作
* - 适用于需要大数值范围的场景
* - 在32位系统上需要特殊处理
*
* 适用场景:
* - 大数值计数器实现
* - 时间戳生成
* - 序列号生成(需要64位范围)
* - 高并发环境下的64位共享变量
* - 需要原子操作的大数值计算
*/
性能特征分析:
/**
* AtomicLong的性能特征:
*
* 时间复杂度:
* - get(): O(1) - 直接读取volatile字段
* - set(): O(1) - 直接写入volatile字段
* - getAndSet(): O(1) 平均,O(∞) 最坏
* - compareAndSet(): O(1) 平均,O(∞) 最坏
* - getAndIncrement(): O(1) 平均,O(∞) 最坏
* - incrementAndGet(): O(1) 平均,O(∞) 最坏
*
* 空间复杂度:
* - O(1) - 只需要存储一个long值和偏移量
*
* 并发特性:
* - 完全线程安全
* - 无锁设计,避免线程阻塞
* - 乐观锁机制,适用于低竞争场景
* - 高竞争场景下可能出现自旋开销
*
* 与synchronized对比:
* - 无竞争:AtomicLong > synchronized
* - 低竞争:AtomicLong > synchronized
* - 高竞争:AtomicLong可能 < synchronized
* - 内存开销:AtomicLong < synchronized
*
* 与AtomicInteger对比:
* - 功能相似:都提供原子操作
* - 数值范围:AtomicLong > AtomicInteger
* - 性能:AtomicInteger略优于AtomicLong
* - 内存使用:AtomicLong > AtomicInteger
*
* CAS操作特点:
* - 乐观锁:假设没有冲突,冲突时重试
* - 非阻塞:不会阻塞其他线程
* - ABA问题:需要额外机制解决
* - 自旋开销:高竞争时CPU使用率可能较高
*
* 内存使用:
* - 每个实例固定开销较小
* - volatile字段保证可见性
* - 及时GC,避免内存泄漏
*
* 适用性:
* - 64位原子操作:性能优异
* - 大数值计数场景:性能优异
* - 复杂同步逻辑:可能不如锁机制
* - 需要精确控制:比锁更灵活
*/
6. 使用示例和最佳实践
/**
* 使用示例:
*
* // 基本使用
* AtomicLong counter = new AtomicLong(0L);
*
* // 原子自增
* long oldValue = counter.getAndIncrement(); // 返回旧值
* long newValue = counter.incrementAndGet(); // 返回新值
*
* // 原子自减
* long oldValue2 = counter.getAndDecrement();
* long newValue2 = counter.decrementAndGet();
*
* // 原子加法
* long oldValue3 = counter.getAndAdd(5L);
* long newValue3 = counter.addAndGet(5L);
*
* // 比较并设置
* boolean success = counter.compareAndSet(10L, 20L);
* if (success) {
* System.out.println("Value updated successfully");
* } else {
* System.out.println("Value update failed");
* }
*
* // 函数式更新(Java 8+)
* long result = counter.updateAndGet(x -> x * 2);
* long previous = counter.getAndUpdate(x -> x + 1);
*
* // 累积操作(Java 8+)
* long accumulated = counter.accumulateAndGet(10L, Long::sum);
* long previousAcc = counter.getAndAccumulate(5L, Math::max);
*
* // 时间戳生成器示例
* class TimestampGenerator {
* private final AtomicLong lastTimestamp = new AtomicLong(0L);
*
* public long getNextTimestamp() {
* long current, next;
* do {
* current = lastTimestamp.get();
* next = System.currentTimeMillis();
* // 确保时间戳单调递增
* if (next <= current) {
* next = current + 1;
* }
* } while (!lastTimestamp.compareAndSet(current, next));
* return next;
* }
*
* public long getCurrentTimestamp() {
* return lastTimestamp.get();
* }
* }
*
* // 大数值计数器示例
* class LargeCounter {
* private final AtomicLong count = new AtomicLong(0L);
*
* public void increment() {
* count.incrementAndGet();
* }
*
* public void add(long delta) {
* count.addAndGet(delta);
* }
*
* public long getCount() {
* return count.get();
* }
*
* public boolean compareAndSetCount(long expect, long update) {
* return count.compareAndSet(expect, update);
* }
*
* // 处理可能的溢出
* public long getAndReset() {
* return count.getAndSet(0L);
* }
* }
*
* // 序列号生成器示例
* class SequenceGenerator {
* private final AtomicLong sequence = new AtomicLong(0L);
*
* public long getNextSequence() {
* return sequence.incrementAndGet();
* }
*
* public long getCurrentSequence() {
* return sequence.get();
* }
*
* public void resetSequence(long newValue) {
* sequence.set(newValue);
* }
*
* // 支持批量获取序列号
* public long[] getNextSequences(int count) {
* long start = sequence.getAndAdd(count);
* long[] sequences = new long[count];
* for (int i = 0; i < count; i++) {
* sequences[i] = start + i;
* }
* return sequences;
* }
* }
*
* 最佳实践:
*
* 1. 正确使用原子操作:
* AtomicLong counter = new AtomicLong(0L);
*
* // 正确的做法:使用原子操作
* counter.incrementAndGet();
*
* // 错误的做法:非原子操作
* // counter.set(counter.get() + 1L); // 不是原子操作!
*
* 2. 合理使用compareAndSet:
* AtomicLong flag = new AtomicLong(0L);
*
* // 正确使用:检查并更新
* public boolean trySetFlag(long expected, long newValue) {
* return flag.compareAndSet(expected, newValue);
* }
*
* // 错误使用:忽略返回值
* // flag.compareAndSet(0L, 1L); // 没有检查返回值
*
* 3. 选择合适的获取方法:
* AtomicLong value = new AtomicLong(0L);
*
* // 当需要旧值时使用getAnd系列方法
* long oldValue = value.getAndIncrement();
* System.out.println("Old value was: " + oldValue);
*
* // 当需要新值时使用incrementAndGet等方法
* long newValue = value.incrementAndGet();
* System.out.println("New value is: " + newValue);
*
* 4. 处理CAS失败的情况:
* AtomicLong value = new AtomicLong(0L);
*
* // 使用循环确保操作成功
* public boolean updateValue(long expected, long newValue) {
* return value.compareAndSet(expected, newValue);
* }
*
* // 或者使用函数式方法
* public long doubleValue() {
* return value.updateAndGet(x -> x * 2L);
* }
*
* 5. 避免ABA问题:
* // ABA问题示例:值从A变为B再变为A
* AtomicLong value = new AtomicLong(10L);
*
* // 线程1准备更新
* long expected = value.get(); // 获取到10
*
* // 线程2执行:10 -> 20 -> 10
* value.compareAndSet(10L, 20L);
* value.compareAndSet(20L, 10L);
*
* // 线程1执行:CAS成功,但实际上中间状态发生了变化
* value.compareAndSet(expected, 30L); // 成功,但可能不是期望的行为
*
* // 解决方案:使用AtomicStampedReference
* AtomicStampedReference<Long> stampedValue =
* new AtomicStampedReference<>(10L, 0);
*
* public boolean updateWithStamp(long expected, long newValue) {
* int[] stampHolder = new int[1];
* long current = stampedValue.get(stampHolder);
* int stamp = stampHolder[0];
* return stampedValue.compareAndSet(expected, newValue, stamp, stamp + 1);
* }
*
* 6. 合理使用函数式更新:
* AtomicLong value = new AtomicLong(0L);
*
* // 简单操作使用专门方法
* value.incrementAndGet(); // 比函数式更快
*
* // 复杂操作使用函数式方法
* long result = value.updateAndGet(x -> {
* // 复杂计算
* return complexCalculation(x);
* });
*
* 7. 处理溢出问题:
* AtomicLong counter = new AtomicLong(Long.MAX_VALUE - 10);
*
* // 注意可能的溢出
* public void safeIncrement() {
* long current = counter.get();
* if (current < Long.MAX_VALUE) {
* counter.incrementAndGet();
* } else {
* // 处理溢出情况
* System.err.println("Counter overflow detected");
* }
* }
*
* // 或者使用饱和算术
* public long getAndIncrementSaturated() {
* long current, next;
* do {
* current = counter.get();
* if (current == Long.MAX_VALUE) {
* return current; // 饱和,不再增加
* }
* next = current + 1;
* } while (!counter.compareAndSet(current, next));
* return current;
* }
*
* 8. 监控和调试:
* AtomicLong counter = new AtomicLong(0L);
*
* // 定期检查计数器状态
* public void logCounterStatus() {
* System.out.println("Current counter value: " + counter.get());
* }
*
* // 性能监控
* public void monitorPerformance() {
* long startTime = System.nanoTime();
* // 执行一些操作
* for (int i = 0; i < 1000000; i++) {
* counter.incrementAndGet();
* }
* long endTime = System.nanoTime();
* System.out.println("Time taken: " + (endTime - startTime) + " ns");
* }
*
* 9. 批量操作优化:
* AtomicLong counter = new AtomicLong(0L);
*
* // 避免频繁的原子操作
* // 错误做法:每次循环都进行原子操作
* // for (int i = 0; i < 1000; i++) {
* // counter.incrementAndGet();
* // }
*
* // 正确做法:批量更新
* long batchSize = 1000L;
* counter.addAndGet(batchSize);
*
* 10. 异常处理:
* AtomicLong value = new AtomicLong(0L);
*
* public void safeUpdate(LongUnaryOperator updateFunction) {
* try {
* value.updateAndGet(updateFunction);
* } catch (Exception e) {
* System.err.println("Update failed: " + e.getMessage());
* // 记录日志或采取其他措施
* }
* }
*
* 11. 性能调优:
* // 在高并发场景下监控性能
* AtomicLong counter = new AtomicLong(0L);
*
* // 使用ThreadLocal减少竞争
* class ThreadLocalCounter {
* private final ThreadLocal<Long> localCounter =
* ThreadLocal.withInitial(() -> 0L);
* private final AtomicLong globalCounter = new AtomicLong(0L);
*
* public void increment() {
* long local = localCounter.get();
* if (local < 1000L) {
* localCounter.set(local + 1L);
* } else {
* globalCounter.addAndGet(local + 1L);
* localCounter.set(0L);
* }
* }
*
* public long getTotal() {
* return globalCounter.get() + localCounter.get();
* }
* }
*/
7. 与其他原子类的比较
/**
* AtomicLong vs AtomicInteger vs AtomicBoolean vs AtomicReference:
*
* AtomicLong:
* - 用于long类型的操作
* - 提供丰富的数学运算方法
* - 64位整数操作
* - 适用于大数值范围的场景
*
* AtomicInteger:
* - 用于int类型的操作
* - 提供与AtomicLong类似的方法
* - 32位整数操作
* - 最常用的原子类
*
* AtomicBoolean:
* - 用于boolean类型的操作
* - 提供get/set/compareAndSet等方法
* - 适用于状态标志
* - 内存效率高
*
* AtomicReference:
* - 用于对象引用的操作
* - 支持CAS操作对象引用
* - 适用于复杂对象的原子操作
* - 可以配合AtomicStampedReference解决ABA问题
*
* 性能对比:
* - 基本操作:AtomicInteger > AtomicLong > AtomicReference > AtomicBoolean
* - 内存使用:AtomicBoolean < AtomicInteger < AtomicLong < AtomicReference
* - 功能丰富度:AtomicReference > AtomicLong ≈ AtomicInteger > AtomicBoolean
*
* 选择建议:
* - 简单计数:AtomicInteger
* - 大数值计数:AtomicLong
* - 状态标志:AtomicBoolean
* - 对象引用:AtomicReference
* - 需要版本控制:AtomicStampedReference
* - 需要标记引用:AtomicMarkableReference
*
* 使用场景:
* - AtomicLong:时间戳、大计数器、需要64位精度的场景
* - AtomicInteger:计数器、序列号、简单的数值操作
* - AtomicBoolean:开关、标志位、简单的状态管理
* - AtomicReference:复杂对象的原子操作、缓存引用
*/
8. 总结
AtomicLong 的核心特性:
-
无锁原子操作:
- 使用CAS实现原子性
- 避免传统锁的开销
- 提供乐观锁机制
-
内存可见性:
- value字段使用volatile修饰
- 保证多线程间的内存可见性
- 确保读操作获取最新值
-
丰富的原子操作:
- 基本的get/set操作
- 自增自减操作
- 比较并设置操作
- 函数式更新操作(Java 8+)
-
64位精度支持:
- 支持long类型的64位操作
- 适用于大数值范围
- 在32位系统上需要特殊处理
-
高性能设计:
- 基于Unsafe的底层操作
- 字段偏移量直接访问
- 自旋重试机制
-
线程安全:
- 所有操作都是线程安全的
- 适用于高并发环境
- 无死锁风险
适用场景:
- 大数值计数器实现
- 时间戳生成
- 序列号生成(需要64位范围)
- 高并发环境下的64位共享变量
- 需要原子操作的大数值计算
注意事项:
- CAS操作可能出现ABA问题
- 高竞争场景下可能有自旋开销
- 不支持复合原子操作
- 需要正确处理CAS的返回值
- 注意选择合适的更新方法
- 处理可能的数值溢出
性能优化建议:
- 根据数据类型和范围选择合适的原子类
- 合理使用compareAndSet避免不必要的操作
- 在高竞争场景下考虑使用ThreadLocal减少竞争
- 监控原子操作的性能表现
- 避免频繁的原子操作,考虑批量更新
- 正确处理ABA问题(必要时使用AtomicStampedReference)
- 选择合适的获取方法(getAnd系列 vs incrementAndGet系列)
- 注意处理数值溢出情况