AtomicInteger

1. 前言

AtomicInteger是Java中的一个原子整数类,它提供了一种在多线程环境下进行原子性操作的方法。所谓原子性操作是指不会被线程调度机制打断的操作;这些操作可以在可能被其他线程影响的情况下作为一个不可分割的整体执行。

在并发编程中,如果多个线程同时对同一个变量进行读取和写入操作,会存在竞态条件(Race Condition),导致数据不一致或错误。为了解决这种问题,Java提供了一系列的原子类,其中包括AtomicInteger。

AtomicInteger可以保证对整型变量的操作是原子性的,比如增加、减少操作。它使用了底层的CAS(Compare and Swap)操作来实现原子性。

2. 介绍CAS

AtomicInteger的实现依赖于底层的CAS(Compare-And-Swap)操作,确保其操作是原子性的。CAS是一种硬件级别的原子操作,通常由处理器直接支持,它可以在多线程环境中保证对变量的修改不会引起竞态条件。

CAS 操作

CAS 操作涉及三个值:

  1. 内存位置(V):需要读取和更新的变量。
  2. 预期值(A):当前线程认为变量应该持有的值。
  3. 新值(B):线程希望将变量的值更新为的新值。

CAS 过程如下:

  • 检查内存位置 V 的当前值是否等于预期值 A。
  • 如果相等,则将内存位置 V 的值更新为新值 B。
  • 如果不相等,则不进行任何操作并返回当前值。

这个过程是一个原子操作,不会被其他线程中断。

AtomicInteger 实现原理

在 Java 中,AtomicInteger 类使用 CAS 操作来实现其方法。以下是它的一些关键方法及其实现原理:

incrementAndGet()

这是 AtomicInteger 类中一个常用方法,用于以原子方式将当前值加 1,并返回加 1 后的值。

java 复制代码
public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}

解释:

  1. 获取当前值 :调用 get() 方法获取当前值。
  2. 计算下一个值:将当前值加 1,得到下一个值。
  3. CAS 操作 :调用 compareAndSet(current, next) 尝试将当前值更新为下一个值。
    • 如果当前值等于预期值(current),则更新成功,返回更新后的值。
    • 如果当前值不等于预期值,则表示在这段时间内已经有其他线程修改了当前值。因此,循环重试,直到更新成功。
compareAndSet(int expect, int update)

这是一个本地方法(native),通常由 JVM 底层通过硬件指令实现。

java 复制代码
public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

解释:

  1. unsafe :使用了 Unsafe 类,这是一个提供底层操作的类。Unsafe 类允许进行低级别的、不受限制的内存操作。
  2. compareAndSwapInt:这是一个本地方法,使用底层的硬件指令来执行 CAS 操作。

为什么 AtomicInteger 是原子的

由上述实现原理可以看出,AtomicInteger 的操作是原子的,原因主要有以下几点:

  1. CAS 操作:底层的 CAS 操作保证了整个比较和交换步骤的原子性。
  2. 硬件支持:现代处理器通常提供对 CAS 操作的原生支持,这样可以确保这些操作在硬件级别上是原子的。
  3. 循环重试:如果 CAS 操作失败(因为其他线程修改了值),AtomicInteger 会自动进行循环重试,直到操作成功。

因此,AtomicInteger 能够在多线程环境中安全地进行整数操作,避免传统锁机制带来的性能损耗,同时确保操作的正确性。

相关推荐
bug菌21 分钟前
Java GUI编程进阶:多线程与并发处理的实战指南
java·后端·java ee
程序猿小D34 分钟前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
极客先躯1 小时前
高级java每日一道面试题-2024年10月3日-分布式篇-分布式系统中的容错策略都有哪些?
java·分布式·版本控制·共识算法·超时重试·心跳检测·容错策略
夜月行者2 小时前
如何使用ssm实现基于SSM的宠物服务平台的设计与实现+vue
java·后端·ssm
程序猿小D2 小时前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
潘多编程2 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
_阿伟_2 小时前
SpringMVC
java·spring
代码在改了2 小时前
springboot厨房达人美食分享平台(源码+文档+调试+答疑)
java·spring boot
猿java3 小时前
使用 Kafka面临的挑战
java·后端·kafka
wclass-zhengge3 小时前
数据结构篇(绪论)
java·数据结构·算法