原子整数

  • AtomicBoolean
  • AtomicInteger
  • AtomicLong

AtomicInteger 常用方法介绍 🚀🔢

AtomicInteger 是 Java 中提供的一种线程安全的整型操作类,属于 java.util.concurrent.atomic 包。相比传统的 int 类型,AtomicInteger 使用 CAS(Compare-And-Swap) 无锁机制实现了高效的线程安全操作,适用于多线程环境下对单个整数变量的原子操作。

接下来,我们来详细了解一下 AtomicInteger 提供的常用方法以及它们的用途。


AtomicInteger 的常用方法 🌟

1. get() - 获取当前值

public final int get();

描述

  • 返回当前的整型值。
  • 在多线程环境下,确保获取的是最新的值。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
System.out.println("当前值: " + atomicInteger.get()); // 输出: 当前值: 10

2. set(int newValue) - 设置新值

public final void set(int newValue);

描述

  • 设置变量为指定值。
  • 是直接赋值,不会考虑线程安全的比较或交换。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
atomicInteger.set(20); // 设置新的值
System.out.println("当前值: " + atomicInteger.get()); // 输出: 当前值: 20

3. getAndSet(int newValue) - 获取当前值然后设置新值

public final int getAndSet(int newValue);

描述

  • 返回当前值,并将变量的值设置为 newValue
  • 在多线程环境下,确保该操作是原子性的,能够避免线程间竞争导致的不一致。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
int oldValue = atomicInteger.getAndSet(20); // 获取旧值并设置成新值
System.out.println("旧值: " + oldValue); // 输出: 旧值: 10
System.out.println("新值: " + atomicInteger.get()); // 输出: 新值: 20

4. incrementAndGet() - 自增并获取新值

public final int incrementAndGet();

描述

  • 将当前值加 1,并返回增加后的新值。
  • 在多线程环境中是线程安全的,适用于计数器等场景。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
System.out.println("自增后的值: " + atomicInteger.incrementAndGet()); // 输出: 自增后的值: 11

5. getAndIncrement() - 获取当前值然后自增

public final int getAndIncrement();

描述

  • 先返回当前值,然后将当前值 +1。
  • 该方法适用于需要先读取值再进行递增的场景。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
System.out.println("当前值: " + atomicInteger.getAndIncrement()); // 输出: 当前值: 10
System.out.println("自增后的值: " + atomicInteger.get());         // 输出: 自增后的值: 11

6. decrementAndGet() - 自减并获取新值

public final int decrementAndGet();

描述

  • 将当前值减 1,并返回减少后的值。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
System.out.println("自减后的值: " + atomicInteger.decrementAndGet()); // 输出: 自减后的值: 9

7. getAndDecrement() - 获取当前值然后自减

public final int getAndDecrement();

描述

  • 先返回当前值,然后将当前值 -1。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
System.out.println("当前值: " + atomicInteger.getAndDecrement()); // 输出: 当前值: 10
System.out.println("自减后的值: " + atomicInteger.get());         // 输出: 自减后的值: 9

8. addAndGet(int delta) - 增加指定值并获取新值

public final int addAndGet(int delta);

描述

  • 将当前值增加指定的 delta 值,并返回添加后的新值。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
System.out.println("增加后的值: " + atomicInteger.addAndGet(5)); // 输出: 增加后的值: 15

9. getAndAdd(int delta) - 获取当前值然后增加指定值

public final int getAndAdd(int delta);

描述

  • 先返回当前值,然后将当前值增加指定的 delta 值。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
System.out.println("当前值: " + atomicInteger.getAndAdd(5)); // 输出: 当前值: 10
System.out.println("增加后的值: " + atomicInteger.get());    // 输出: 增加后的值: 15

10. compareAndSet(int expectedValue, int newValue) - 比较并设置新值

public final boolean compareAndSet(int expectedValue, int newValue);

描述

  • 如果当前值与 expectedValue 相等,则将其更新为 newValue,返回 true;否则不更新,返回 false
  • 这是 CAS 操作的核心方法,适合解决多线程环境下的竞争问题。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
boolean success = atomicInteger.compareAndSet(10, 20); // 当前值是 10,更新为 20
System.out.println("更新成功了吗?" + success); // 输出: 更新成功了吗?true
System.out.println("当前值: " + atomicInteger.get());   // 输出: 当前值: 20

11. compareAndExchange(int expectedValue, int newValue) - 比较并替换,返回旧值

public final int compareAndExchange(int expectedValue, int newValue);

描述

  • 如果当前值与 expectedValue 相等,则将其更新为 newValue 并返回旧值;如果不相等,返回当前值。

示例代码

AtomicInteger atomicInteger = new AtomicInteger(10);
int oldValue = atomicInteger.compareAndExchange(10, 20); // 交换成功,旧值返回
System.out.println("原值: " + oldValue); // 输出: 原值: 10
System.out.println("当前值: " + atomicInteger.get());   // 输出: 当前值: 20

AtomicInteger 的高级方法 🚀

12. updateAndGet(IntUnaryOperator updateFunction) - 按指定规则更新值并返回新值

public final int updateAndGet(IntUnaryOperator updateFunction);

功能

  • 根据提供的函数 (如 lambda 表达式) 对当前值进行更新,并返回更新后的新值。

示例

AtomicInteger atomicInteger = new AtomicInteger(10);
int newValue = atomicInteger.updateAndGet(value -> value * 2); // 将值翻倍
System.out.println("更新后的值: " + newValue); // 输出: 更新后的值: 20

13. accumulateAndGet(int x, IntBinaryOperator accumulatorFunction) - 按累积函数计算并更新值

public final int accumulateAndGet(int x, IntBinaryOperator accumulatorFunction);

功能

  • 通过累积函数指定规则,将当前值与参数 x 结合并计算出结果,然后将其更新为新值。

示例

AtomicInteger atomicInteger = new AtomicInteger(10);
int newValue = atomicInteger.accumulateAndGet(5, (current, increment) -> current + increment); // 当前值 + 参数
System.out.println("累积后的值: " + newValue); // 输出: 累积后的值: 15

适用场景 💼

  • 计数器:用于记录线程池任务执行的数量。
  • ID 生成器:生成线程安全的唯一 ID。
  • 限流器:实现简单的线程安全下限或上限数据控制。
  • 共享数据更新:如统计操作或日志追踪的安全计数。

AtomicBoolean 的常用方法

了解 AtomicBoolean 的常用方法 🧠🔒

AtomicBoolean 是 Java 中提供的一种线程安全的布尔类型操作类,属于 java.util.concurrent.atomic 包。它采用 CAS(Compare-And-Swap) 无锁机制,确保在多线程环境下对布尔值的原子操作。相比普通的 boolean 类型,AtomicBoolean 是专为并发编程设计的,适合检查标志位(如任务完成状态、控制共享资源访问等)。

以下是 AtomicBoolean 的常用方法和用途,它非常适合实现线程安全布尔逻辑。


AtomicBoolean 的常用方法 🌟

1. get() - 获取当前值 🟢

public final boolean get();

描述

  • 返回当前的布尔值。
  • 在多线程访问环境下,可以确保获取的是最新的值。

示例代码

AtomicBoolean atomicBoolean = new AtomicBoolean(true);
System.out.println("当前状态: " + atomicBoolean.get()); // 输出: 当前状态: true

2. set(boolean newValue) - 设置新值 🟡

public final void set(boolean newValue);

描述

  • 将布尔变量设置为指定的新值。
  • 这是直接赋值,不涉及任何比较逻辑或安全检查。

示例代码

AtomicBoolean atomicBoolean = new AtomicBoolean(false);
atomicBoolean.set(true);  // 设置为 true
System.out.println("当前状态: " + atomicBoolean.get()); // 输出: 当前状态: true

3. getAndSet(boolean newValue) - 获取当前值然后设置新值 🔄

public final boolean getAndSet(boolean newValue);

描述

  • 返回当前值,同时将变量的值更新为 newValue
  • 在多线程环境中,确保该操作是原子性的。

示例代码

AtomicBoolean atomicBoolean = new AtomicBoolean(false);
boolean oldValue = atomicBoolean.getAndSet(true); // 获取旧值并更新为 true
System.out.println("旧状态: " + oldValue);         // 输出: 旧状态: false
System.out.println("新状态: " + atomicBoolean.get()); // 输出: 新状态: true

4. compareAndSet(boolean expected, boolean newValue) - 比较并设置 🧪

public final boolean compareAndSet(boolean expected, boolean newValue);

描述

  • 如果当前值与预期值 expected 相等,则更新为 newValue,返回 true;否则不更新,返回 false
  • CAS 操作的核心方法,适合解决多线程环境下布尔值的竞争问题。

示例代码

AtomicBoolean atomicBoolean = new AtomicBoolean(false);
boolean success = atomicBoolean.compareAndSet(false, true); // 预期值是 false,更新为 true
System.out.println("更新成功了吗?" + success);       // 输出: 更新成功了吗?true
System.out.println("新状态: " + atomicBoolean.get()); // 输出: 新状态: true

5. weakCompareAndSet(boolean expected, boolean newValue) - 弱比较并设置 🔍

public final boolean weakCompareAndSet(boolean expected, boolean newValue);

描述

  • compareAndSet 很像,但不保证所有条件下操作都成功。通常用于性能优化,因为它可能在某些硬件环境下效率更高。
  • 适用于一些不要求严格 CAS 控制的场景。

示例代码

AtomicBoolean atomicBoolean = new AtomicBoolean(false);
boolean success = atomicBoolean.weakCompareAndSet(false, true); // 尝试更新
System.out.println("弱比较更新成功?" + success);          // 输出: 弱比较更新成功?true 或 false
System.out.println("新状态: " + atomicBoolean.get()); // 输出可能会是 true 或 false,取决于硬件实现

6. lazySet(boolean newValue) - 延迟设置 🕐

public final void lazySet(boolean newValue);

描述

  • 将变量更新为新值,但更新可能是 “延迟” 的,不会立即对其他线程可见。
  • 目的是优化性能,避免多线程同时写操作时的开销。

示例代码

AtomicBoolean atomicBoolean = new AtomicBoolean(false);
atomicBoolean.lazySet(true); // 延迟设置为 true
System.out.println("当前状态: " + atomicBoolean.get()); // 输出: 当前状态: true(多线程情况下可能稍后更新)

适用场景 💼

AtomicBoolean 的线程安全特性使它非常适合以下场景:

场景 1: 控制资源访问 🛡️

例如在多线程情况下控制某段代码的执行:

AtomicBoolean lock = new AtomicBoolean(false);

public void accessResource() {
    if (lock.compareAndSet(false, true)) {
        try {
            System.out.println(Thread.currentThread().getName() + " 正在访问资源...");
            // 模拟资源访问
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.set(false); // 释放锁
        }
    } else {
        System.out.println(Thread.currentThread().getName() + " 无法访问资源,资源已被占用");
    }
}

运行示例:

AtomicBoolean lock = new AtomicBoolean(false);
Runnable task = () -> accessResource();
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();

场景 2: 中断控制 🔌

用于线程间布尔标志的安全传递,确保能准确触发操作:

AtomicBoolean stopFlag = new AtomicBoolean(false);

public void doWork() {
    while (!stopFlag.get()) {
        System.out.println(Thread.currentThread().getName() + " 正在工作...");
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public void stopWork() {
    stopFlag.set(true);
    System.out.println("工作已停止!");
}

运行示例:

AtomicBoolean stopFlag = new AtomicBoolean(false);
Thread worker = new Thread(() -> doWork());
worker.start();

// 模拟一段处理后停止工作
Thread.sleep(500);
stopWork();

场景 3: 状态同步 🔄

例如协作线程之间共享完成状态:

AtomicBoolean isCompleted = new AtomicBoolean(false);

class Task extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 正在执行任务...");
        try {
            Thread.sleep(1000); // 模拟任务处理
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        isCompleted.set(true);
        System.out.println(Thread.currentThread().getName() + " 完成任务");
    }
}

运行示例:

AtomicBoolean isCompleted = new AtomicBoolean(false);
Thread t1 = new Task();
t1.start();

while (!isCompleted.get()) {
    System.out.println("等待任务完成...");
    Thread.sleep(200); // 每 200ms 检查一次状态
}
System.out.println("任务已完成!");

总结 🧠

AtomicBoolean 是处理多线程环境下布尔值的利器。它提供了以下功能:

  1. 安全地读取和更新布尔标志位。
  2. 高效的 CAS 机制,适用于控制资源访问、工作中断等场景。
  3. 延迟和弱比较等优化方法,提升性能。