Java AtomicInteger原理用法源码详解
基本原理
Java 中的 AtomicInteger 是一个原子类,用于实现对整数类型的原子操作。它提供了一系列方法,如 get()、set()、incrementAndGet()、compareAndSet() 等,可以在多线程环境下安全地进行原子操作。通过使用 AtomicInteger,可以避免使用显式的锁来保护共享整数变量,从而提高并发性能。它适用于许多并发场景,如计数器、标记位等。
AtomicInteger 的原理基于 CAS(Compare-And-Swap)操作。它内部使用了 Unsafe 类或者其他底层的原子操作机制来实现线程安全的操作。通过 CAS 操作,AtomicInteger 可以保证在多线程环境下对整数值的修改是原子性的,避免了竞态条件和数据不一致等问题。
AtomicInteger 的主要特点和原理如下:
- 内部使用
volatile修饰的 int 变量:AtomicInteger内部有一个被volatile修饰的 int 变量,用于存储整数值。volatile关键字确保了变量的可见性,使得对该变量的读写操作具有原子性。 - 使用 CAS 操作进行原子更新:
AtomicInteger中的原子操作方法都是基于 CAS 操作实现的。CAS 操作包括比较内存中的值与预期值是否相等,如果相等则更新为新值,否则操作失败。CAS 操作利用底层硬件提供的原子指令,确保操作的原子性。 - 循环重试:由于 CAS 操作可能在多线程环境下失败,因此
AtomicInteger在实现中使用了循环重试的机制。如果 CAS 操作失败,它会不断尝试进行 CAS 操作,直到成功为止。
注意事项
-
AtomicInteger并不能完全替代Integer类,因为它并没有提供自动装箱和拆箱的功能。 -
虽然
AtomicInteger提供了原子操作,但仍然需要根据具体情况考虑原子类的使用范围和正确性。有时候,可能需要额外的同步手段来保证一些复合操作的原子性。假设需要对一个计数器进行原子递增和条件检查,以决定是否执行某个操作。以下是一个示例代码:
if (counter.incrementAndGet() >= threshold) {
// 执行操作
}
尽管递增操作和条件检查各自都是原子的,但由于两个操作之间存在竞态条件,可能会导致结果不一致。因为在判断条件后,其他线程可能已经对计数器进行了修改。在这种情况下,可以使用额外的同步手段,如锁(`synchronized`)或者显示的使用 `Lock` 接口,来保证多个操作的原子性,可以确保递增操作、条件检查和操作的执行之间是原子的,避免了竞态条件。
```java
synchronized (lock) {
if (counter.incrementAndGet() >= threshold) {
// 执行操作
}
}
基本方法
以下是对 AtomicInteger 类中提供的方法进行总结:
-
AtomicInteger(int initialValue):使用给定的初始值创建一个新的AtomicInteger对象。 -
AtomicInteger():创建一个新的AtomicInteger对象,并将初始值设为 0。 -
int get():获取当前存储的整数值。 -
void set(int newValue):设置整数值为指定的新值。 -
void lazySet(int newValue):最终将整数值设置为指定的新值。不保证立即生效,可能会延迟。 -
int getAndSet(int newValue):将整数值设置为指定的新值,并返回先前的值。 -
boolean compareAndSet(int expect, int update):如果当前值等于预期值,则原子地将整数值设置为指定的新值,并返回操作是否成功。 -
boolean weakCompareAndSet(int expect, int update):与compareAndSet()方法类似,但不提供强有力的保证和排序保证。 -
int getAndIncrement():先返回当前值,然后将整数值增加 1。 -
int getAndDecrement():先返回当前值,然后将整数值减少 1。 -
int getAndAdd(int delta):先返回当前值,然后将整数值增加指定的增量。 -
int incrementAndGet():将整数值增加 1,然后返回更新后的值。 -
int decrementAndGet():将整数值减少 1,然后返回更新后的值。 -
int addAndGet(int delta):将整数值增加指定的增量,然后返回更新后的值。 -
int getAndUpdate(IntUnaryOperator updateFunction):先获取当前值,然后将整数值更新为通过应用给定函数得到的新值,返回先前的值。 -
int updateAndGet(IntUnaryOperator updateFunction):先获取当前值,然后将整数值更新为通过应用给定函数得到的新值,返回更新后的值。 -
int getAndAccumulate(int x, IntBinaryOperator accumulatorFunction):先获取当前值,然后将整数值与给定值通过应用给定函数进行累积计算,返回先前的值。 -
int accumulateAndGet(int x, IntBinaryOperator accumulatorFunction):先获取当前值,然后将整数值与给定值通过应用给定函数进行累积计算,返回更新后的值。 -
String toString():以字符串形式返回当前存储的整数值。 -
int intValue():将当前存储的整数值转换为int类型并返回。 -
long longValue():将当前存储的整数值转换为long类型并返回。 -
float floatValue():将当前存储的整数值转换为float类型并返回。 -
double doubleValue():将当前存储的整数值转换为double类型并返回。
这些方法允许原子地对整数值进行各种操作,确保在多线程环境下的线程安全性。
场景示例
以下是几个适用场景和示例:
- 计数器(Counter):
AtomicInteger可以用作计数器,在多线程环境下实现原子的自增、自减操作。例如,统计网站访问次数或任务完成数量等。
public class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public void decrement() {
count.decrementAndGet();
}
public int getCount() {
return count.get();
}
}
- 并发任务处理:在并发任务处理中,可以使用
AtomicInteger来控制任务的执行顺序或限制同时执行的任务数量。
import java.util.concurrent.atomic.AtomicInteger;
public class TaskProcessor {
private static final int MAX_CONCURRENT_TASKS = 10;
private AtomicInteger activeTasks = new AtomicInteger(0);
public void processTask(Runnable task) {
// 检查是否达到最大并发任务数
while (activeTasks.get() >= MAX_CONCURRENT_TASKS) {
// 等待其他任务完成后再继续执行

本文详细解释了JavaAtomicInteger的基本原理,包括其基于CAS操作的实现,注意事项,以及提供的一系列原子操作方法。文章还探讨了AtomicInteger在多线程场景中的应用,如计数器、并发任务处理和共享变量同步。
最低0.47元/天 解锁文章
2388

被折叠的 条评论
为什么被折叠?



