导读:本期聚焦于小伙伴创作的《如何应用原子变量类实战解决多线程环境下的变量自增线程安全难点》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何应用原子变量类实战解决多线程环境下的变量自增线程安全难点》有用,将其分享出去将是对创作者最好的鼓励。

在多线程并发编程的实际开发中,多个线程同时对同一个整型变量执行自增操作是非常常见的场景,但普通的自增操作并不具备原子性,很容易出现最终结果小于预期的情况,这就是典型的线程安全问题。要解决这个问题,开发者可以选择不同的方案,其中原子变量类是兼顾性能和正确性的优选方案。

如何应用原子变量类实战解决多线程环境下的变量自增线程安全难点

普通变量自增的线程安全问题演示

我们先来看一个不使用任何同步措施的自增示例,启动10个线程,每个线程对同一个整型变量执行1000次自增操作,预期最终结果应该是10000。

public class NormalIncrementTest {
    // 普通整型变量
    private static int count = 0;

    public static void main(String[] args) throws InterruptedException {
        // 创建10个线程
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                // 每个线程自增1000次
                for (int j = 0; j < 1000; j++) {
                    count++;
                }
            }).start();
        }
        // 等待所有线程执行完成
        Thread.sleep(2000);
        // 输出最终结果
        System.out.println("最终count值:" + count);
    }
}

多次运行上述代码,你会发现最终结果往往小于10000,这是因为count++操作实际上分为三步:读取count当前值、将值加1、写回新的count值。多个线程同时执行时,可能出现两个线程读取到同一个旧值,各自加1后写回,导致一次自增操作被覆盖,最终结果偏小。

传统解决线程安全自增的方案及不足

最常用的传统方案是使用synchronized关键字对自增操作加锁,保证同一时间只有一个线程能执行自增操作。

public class SynchronizedIncrementTest {
    private static int count = 0;

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    // 使用synchronized加锁
                    synchronized (SynchronizedIncrementTest.class) {
                        count++;
                    }
                }
            }).start();
        }
        Thread.sleep(2000);
        System.out.println("最终count值:" + count);
    }
}

这种方式能够保证结果正确,但synchronized是重量级锁,线程获取不到锁时会进入阻塞状态,涉及用户态和内核态的切换,性能开销比较大,在高并发场景下会成为性能瓶颈。

原子变量类解决自增线程安全的原理

原子变量类位于java.util.concurrent.atomic包下,比如AtomicInteger就是针对整型变量的原子类,它的核心是基于CAS(Compare And Swap,比较并交换)机制实现的。

CAS操作包含三个核心参数:内存地址V、旧的预期值A、要修改的新值B。操作时先比较内存地址V上的值是否等于预期值A,如果相等,就把V的值更新为B,否则不做任何操作,整个过程是原子性的。

AtomicInteger的自增方法incrementAndGet就是通过循环CAS实现的:先获取当前值,计算加1后的新值,然后调用CAS尝试更新,如果更新失败(说明有其他线程修改了值),就重新获取当前值重试,直到更新成功。

原子变量类实战解决自增线程安全问题

我们用AtomicInteger来改写前面的自增示例,代码如下:

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIncrementTest {
    // 使用原子整型变量,初始化为0
    private static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    // 调用原子自增方法,相当于count++
                    count.incrementAndGet();
                }
            }).start();
        }
        Thread.sleep(2000);
        // 获取最终值
        System.out.println("最终count值:" + count.get());
    }
}

运行上述代码,你会发现最终结果始终是10000,完全符合预期。这种方式不需要加锁,线程不会阻塞,性能比synchronized方案更好,同时保证了操作的原子性。

原子变量类的常用方法说明

除了incrementAndGet方法,AtomicInteger还有很多实用的方法,常用方法如下:

方法名作用说明
get()获取当前变量的值
set(int newValue)设置变量为新的值
incrementAndGet()变量自增1,返回自增后的值
getAndIncrement()变量自增1,返回自增前的值
decrementAndGet()变量自减1,返回自减后的值
addAndGet(int delta)变量加上指定的delta值,返回相加后的值
compareAndSet(int expect, int update)如果当前值等于expect,就更新为update,返回是否更新成功

使用原子变量类的注意事项

  • 原子变量类只能保证单个变量的操作是原子性的,如果需要保证多个变量的组合操作原子性,还是需要使用锁或者其他同步机制。
  • CAS操作在高竞争场景下会出现大量的重试,可能会消耗一定的CPU资源,这种情况下需要评估是否适合使用原子变量类。
  • 除了AtomicInteger,该包下还有AtomicLongAtomicBooleanAtomicReference等,分别对应长整型、布尔型、引用类型的原子操作,可根据实际场景选择。
原子变量类是多线程场景下处理单个变量原子操作的高效方案,相比传统的锁机制有更好的性能表现,开发者在实际开发中遇到类似的自增、自减等线程安全问题,可以优先考虑使用原子变量类解决。

原子变量类多线程线程安全变量自增修改时间:2026-06-28 01:51:40

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。