1. 基本类型原子类
- AtomicInteger:用于对整数进行原子操作,如
incrementAndGet()
方法可以原子地将当前值加1并返回新值,getAndSet()
方法可以原子地设置新值并返回旧值。 - AtomicLong:和AtomicInteger类似,用于长整型的原子操作。在处理高并发场景下的计数(例如网站的访问量计数等场景),如果计数可能超出
int
范围,就可以使用AtomicLong。 - AtomicBoolean:提供原子性的布尔值操作。例如在多线程环境下,用于标志某个资源是否被占用或者某个任务是否完成等场景。
2. 引用类型原子类
- AtomicReference:可以原子地更新引用对象。比如在实现一个简单的对象缓存时,使用AtomicReference可以确保在多线程环境下安全地更新缓存中的对象引用。
- AtomicStampedReference:在AtomicReference的基础上,增加了一个“版本号”(或者称为“时间戳”)的概念。它可以用于解决在并发环境下,对象可能被多次修改而导致的ABA问题。例如,在一个链表结构的并发操作中,一个节点可能被删除后又插入相同的节点,使用AtomicStampedReference可以区分这种情况。
- AtomicMarkableReference:也是一种带有标记的原子引用类。它主要用于标记对象是否被删除或者其他简单的二元状态标记场景,相比AtomicStampedReference更简单,只关心两种状态。
3. 数组类型原子类
- AtomicIntegerArray:对整数数组进行原子操作。假设一个多线程环境下的图像处理程序,需要对图像像素数组(假设像素值用整数表示)进行操作,AtomicIntegerArray可以保证每个像素值的操作原子性。
- AtomicLongArray:用于长整型数组的原子操作。例如在一个金融数据分析系统中,可能有一个长整型数组用于记录多个金融产品的交易金额累计值,在多线程环境下更新这些数据时可以使用AtomicLongArray。
- AtomicReferenceArray:对引用数组进行原子操作。比如在一个游戏服务器中,有一个玩家对象引用数组,在多线程环境下更新玩家对象引用(如玩家重新登录等情况)可以使用AtomicReferenceArray来保证操作的原子性。
4. 字段更新器原子类(用于原子地更新对象的某个字段)
- AtomicIntegerFieldUpdater:用于原子地更新对象中的
int
类型字段。例如,在一个复杂的业务对象中,有一个int
类型的状态字段,在多线程环境下需要原子地更新这个状态字段时可以使用。 - AtomicLongFieldUpdater:用于原子地更新对象中的
long
类型字段,应用场景和AtomicIntegerFieldUpdater类似,只是针对长整型字段。 - AtomicReferenceFieldUpdater:用于原子地更新对象中的引用类型字段。例如在一个包含用户对象的业务对象中,有一个引用类型字段表示用户的当前权限对象,在多线程环境下需要原子地更新这个权限对象引用时可以使用。
5. Adder和Accumulator类(Java 8引入)
- LongAdder:
- 介绍:它是对
AtomicLong
的一种优化,在高并发的场景下提供了更高的性能。LongAdder
在内部维护了多个变量(Cell数组)来分散并发更新的压力,而不是像AtomicLong
那样在一个变量上进行竞争操作。 - 应用场景和示例:例如在一个大规模的分布式系统中,统计各个节点的请求处理数量。多个线程频繁地更新这个计数,使用
LongAdder
可以有效减少竞争,提高并发性能。
import java.util.concurrent.atomic.LongAdder;
class RequestCounter {
private LongAdder counter = new LongAdder();
public void increment() {
counter.add(1);
}
public long getCount() {
return counter.sum();
}
}
- DoubleAdder:
- 介绍:类似于
LongAdder
,不过它是用于双精度浮点数(double
)的累加器。在需要对浮点数进行高并发累加操作的场景下很有用。 - 应用场景和示例:比如在一些科学计算或者金融数据统计场景中,需要对一系列双精度浮点数进行求和,并且这些求和操作可能会被多个线程同时执行。
- LongAccumulator:
- 介绍:
LongAccumulator
提供了一种更灵活的方式来对长整型数据进行累积操作。它允许你指定一个自定义的累积函数,而不仅仅是简单的加法。 - 应用场景和示例:例如,你可以定义一个乘法累积函数来计算一系列数字的乘积。
import java.util.concurrent.atomic.LongAccumulator;
class ProductCalculator {
private LongAccumulator accumulator;
public ProductCalculator() {
accumulator = new LongAccumulator((x, y) -> x * y, 1);
}
public void addValue(long value) {
accumulator.accumulate(value);
}
public long getProduct() {
return accumulator.get();
}
}
- DoubleAccumulator:
- 介绍:和
LongAccumulator
类似,但是用于双精度浮点数的累积操作,并且可以自定义累积函数,适用于更复杂的浮点数累积计算场景。
转自AI豆包