Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java基础

    • Java概述
    • Java语法
    • 面向对象编程
    • Java数组
    • String字符串
    • 异常处理
  • Java集合

    • Java集合概述
    • ArrayList
    • LinkedList
    • HashMap
    • LinkedHashMap
    • HashSet
    • TreeMap
    • Queue&Deque
  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
    • 原子操作类Atomic
      • 1. 什么是原子操作类
      • 2. 常见的原子类
        • 2.1 AtomicInteger
        • 2.2 AtomicLong
        • 2.3 AtomicBoolean
        • 2.4 AtomicReference
      • 3. 使用场景
      • 4. 原子类与锁的比较
      • 5. 总结
    • 并发锁
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
    • ScheduledThreadPoolExecutor
    • CompletableFuture
  • Java IO

    • Java IO概述
  • JVM

    • JVM概述
  • Java
  • Java并发
Wray
2024-10-31
目录

原子操作类Atomic

原子操作类(Atomic)是 Java 并发编程中的重要组成部分,用于在多线程环境中实现对基本类型的原子性操作。java.util.concurrent.atomic 包中的原子类提供了一些高效的无锁操作,通过硬件支持的原子操作来避免使用锁,从而提升并发性能。

# 1. 什么是原子操作类

  • 原子性:原子性指的是一个操作不可中断,即使在多线程环境下,这个操作一旦开始执行,就不会被其他线程干扰。原子操作类提供了对共享变量的无锁原子操作,确保操作的原子性。
  • CAS(Compare-And-Swap)机制:原子类内部依赖于硬件支持的 CAS 操作实现无锁更新。CAS 包含三个操作数——内存位置(要读取和更新的变量)、预期的旧值、要更新的新值。CAS 只有在变量的当前值等于预期值时,才会将其更新为新值,这样就保证了更新的原子性。

# 2. 常见的原子类

Java 中常用的原子类包括 AtomicInteger、AtomicLong、AtomicBoolean 以及 AtomicReference,它们分别用于对基本类型和引用类型进行原子操作。

# 2.1 AtomicInteger

  • 概念:AtomicInteger 是一个支持原子操作的 int 类型。它提供了一些线程安全的方法来更新整数值。
  • 常用方法:
    • get():获取当前值。
    • set(int newValue):设置为指定值。
    • incrementAndGet():原子地自增并返回新值。
    • compareAndSet(int expect, int update):如果当前值等于预期值,则原子地更新为新值。

示例代码:

AtomicInteger count = new AtomicInteger(0);

Runnable worker = () -> {
    for (int i = 0; i < 5; i++) {
        int newValue = count.incrementAndGet();
        System.out.println(Thread.currentThread().getName() + " incremented count to " + newValue);
    }
};

for (int i = 0; i < 3; i++) {
    new Thread(worker).start();
}

在这个例子中,多个线程同时对 count 进行自增操作,AtomicInteger 确保了操作的线程安全。

# 2.2 AtomicLong

  • 概念:AtomicLong 类与 AtomicInteger 类类似,只不过它用于 long 类型的原子操作。
  • 常用方法:
    • getAndAdd(long delta):原子地将当前值增加指定的 delta,并返回旧值。
    • addAndGet(long delta):原子地将当前值增加指定的 delta,并返回新值。

# 2.3 AtomicBoolean

  • 概念:AtomicBoolean 提供了对布尔值的原子操作,适用于需要线程安全地修改标志位的场景。
  • 常用方法:
    • compareAndSet(boolean expect, boolean update):如果当前值等于预期值,则原子地将其更新为新值。
    • getAndSet(boolean newValue):获取当前值并将其设置为新值。

示例代码:

AtomicBoolean flag = new AtomicBoolean(false);

Runnable task = () -> {
    if (flag.compareAndSet(false, true)) {
        System.out.println(Thread.currentThread().getName() + " set the flag to true");
    } else {
        System.out.println(Thread.currentThread().getName() + " could not set the flag");
    }
};

for (int i = 0; i < 3; i++) {
    new Thread(task).start();
}

在这个例子中,只有一个线程能够成功将 flag 设置为 true,其余线程将会失败。

# 2.4 AtomicReference

  • 概念:AtomicReference 提供了对引用类型变量的原子操作,适用于需要原子性更新引用对象的场景。
  • 常用方法:
    • get():获取当前引用。
    • compareAndSet(V expect, V update):如果当前引用等于预期引用,则原子地将其更新为新的引用。

示例代码:

AtomicReference<String> reference = new AtomicReference<>("Initial");

Runnable updater = () -> {
    String oldValue = reference.get();
    String newValue = oldValue + " -> Updated by " + Thread.currentThread().getName();
    if (reference.compareAndSet(oldValue, newValue)) {
        System.out.println(Thread.currentThread().getName() + " successfully updated the reference");
    }
};

for (int i = 0; i < 3; i++) {
    new Thread(updater).start();
}

在这个例子中,AtomicReference 确保多个线程可以安全地更新引用对象。

# 3. 使用场景

  • 计数器:AtomicInteger 和 AtomicLong 非常适合用作计数器,例如请求数、连接数等。
  • 状态标志:AtomicBoolean 适合用于控制任务是否被执行,例如单次任务执行标志位。
  • CAS 实现乐观锁:原子类通过 CAS 操作实现无锁更新,适用于高并发环境下对资源的乐观锁控制。

# 4. 原子类与锁的比较

  • 性能:原子类使用 CAS 操作实现无锁更新,在大多数情况下性能优于使用锁的方式,尤其是在竞争不激烈的环境下。
  • 复杂性:原子类适用于简单的变量更新,如果涉及多个变量的复杂更新逻辑,使用锁(如 synchronized 或 ReentrantLock)可能更加直观和方便。

# 5. 总结

原子操作类是 Java 并发包中的重要组成部分,通过无锁的方式实现了对共享变量的原子更新,保证了多线程环境下的线程安全。理解 AtomicInteger、AtomicLong、AtomicBoolean 以及 AtomicReference 的使用场景,有助于在高并发编程中编写更加高效和可靠的代码。在使用原子类时,如果操作复杂或涉及多个变量的更新,建议考虑使用锁来确保线程安全。

上次更新: 2024/11/01, 13:45:14
并发工具类
并发锁

← 并发工具类 并发锁→

Copyright © 2023-2024 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式