返回

原子性操作 AtomicInteger

见解分享

AtomicInteger 源码分析

在并发环境中,共享变量的原子性操作至关重要。AtomicInteger 是 Java 中一种保证原子性操作的类,它提供了一种线程安全的 int 类型变量。本文将深入分析 AtomicInteger 的源码,探索其内部机制和使用方法。

源码分析

1. 类的定义

public class AtomicInteger extends Number {
    private static final long serialVersionUID = 8673204282481053485L;
    private volatile int value;
}

AtomicInteger 类继承自 Number 类,它将一个 int 类型变量 value 声明为 volatile 类型,这确保了变量的可见性。

2. 字段属性

除了 value 字段外,AtomicInteger 类还定义了以下字段:

  • BASE :一个静态 final 常量,代表 int 变量的底层偏移量。
  • UPDATER :一个静态 final Unsafe 对象,用于执行原子操作。
  • eventCount :一个静态 final long 类型的事件计数器,用于通知监听器。

3. 构造方法

AtomicInteger 类提供了几个构造方法,允许您指定不同的初始化值:

public AtomicInteger() {
    this(0);
}

public AtomicInteger(int initialValue) {
    value = initialValue;
}

4. 方法

AtomicInteger 类提供了几个方法来操作 value 字段:

  • get() :返回 value 的当前值。
  • set(int newValue) :设置 value 的值,此操作不是原子性的。
  • compareAndSet(int expect, int update) :如果 value 的当前值与 expect 相等,则将其更新为 update。返回 true 表示成功,否则返回 false。
  • getAndIncrement() :原子地增加 value 并返回之前的值。
  • getAndDecrement() :原子地减少 value 并返回之前的值。
  • getAndAdd(int delta) :原子地将 delta 加到 value 上并返回之前的值。
  • lazySet(int newValue) :在某些情况下,原子地设置 value 的值。

CAS 操作

从方法中可以看出,所有修改值的操作都是通过 Unsafe 对象操作的,这个里面都是 native 方法。CAS 操作是直接地址操作,通过 C 来操作的。

使用 AtomicInteger

AtomicInteger 可以用于保证并发环境中共享变量的原子性操作。例如,以下代码使用 AtomicInteger 来实现一个计数器:

import java.util.concurrent.atomic.AtomicInteger;

public class Counter {
    private final AtomicInteger count = new AtomicInteger(0);

    public int getCount() {
        return count.get();
    }

    public void increment() {
        count.getAndIncrement();
    }
}

在多线程环境中使用 Counter 类时,可以确保对 count 变量的修改是原子的,从而避免了竞态条件和数据不一致的情况。

限制

在使用 AtomicInteger 时,需要注意以下限制:

  • 范围限制 :AtomicInteger 只能表示 32 位 int 类型的值,超过范围可能会导致溢出。
  • 精确度限制 :在高并发场景中,AtomicInteger 的 CAS 操作可能会导致性能开销。
  • 可见性限制 :AtomicInteger 只能保证变量的可见性,但不能保证其有序性。

结论

AtomicInteger 是 Java 中一种方便且高效的工具,可以实现共享变量的原子性操作。通过了解其源码和使用方法,我们可以充分利用 AtomicInteger 来提高并发应用程序的可靠性和可维护性。