You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程环境下AtomicInteger计数不符合预期的问题求助

嘿,这个问题我太熟了!你遇到的计数远小于预期的情况,大概率是因为没有让所有线程共享同一个AtomicInteger实例,或者在更新时误用了非原子的操作逻辑。别担心,我给你拆解清楚并给出正确的实现方案~

问题根源

AtomicInteger本身是线程安全的,它的原子方法(比如incrementAndGet())已经帮你处理了竞态条件。但如果你的代码里每个线程都创建了自己的AtomicInteger实例,那每个线程其实都在独立计数,最后汇总的时候自然得不到1000的结果。另外,如果你用了counter.set(counter.get() + 1)这种非原子操作,也会因为多个线程同时读取和写入导致计数丢失。

正确实现思路

要解决这个问题,核心就是两点:

  • 让所有线程共享同一个AtomicInteger对象,不能每个线程单独初始化
  • 必须使用AtomicInteger提供的原子更新方法,比如incrementAndGet()、addAndGet(1),这些方法是线程安全的,不会出现计数丢失

示例代码

错误示范(可能是你当前的写法)

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class WrongCounterDemo {
    static class TaskThread extends Thread {
        // 每个线程自己持有计数器实例
        private AtomicInteger counter = new AtomicInteger(0);

        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                counter.incrementAndGet();
            }
        }

        public AtomicInteger getCounter() {
            return counter;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        List<TaskThread> threads = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            threads.add(new TaskThread());
        }

        // 启动线程
        for (Thread t : threads) {
            t.start();
        }

        // 等待所有线程结束
        for (Thread t : threads) {
            t.join();
        }

        // 这里如果只取某一个线程的计数器,结果只会是100,远小于1000
        System.out.println("Total count: " + threads.get(0).getCounter().get());
    }
}

正确实现

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class CorrectCounterDemo {
    static class TaskThread extends Thread {
        // 共享的计数器,通过构造方法传入
        private final AtomicInteger sharedCounter;

        public TaskThread(AtomicInteger sharedCounter) {
            this.sharedCounter = sharedCounter;
        }

        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                // 使用原子递增方法,线程安全
                sharedCounter.incrementAndGet();
                // 如果需要批量增加,比如每次加5,用sharedCounter.addAndGet(5)
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 创建唯一的共享计数器实例
        AtomicInteger totalCounter = new AtomicInteger(0);
        List<TaskThread> threads = new ArrayList<>();

        // 给每个线程传入同一个计数器
        for (int i = 0; i < 10; i++) {
            threads.add(new TaskThread(totalCounter));
        }

        // 启动所有线程
        for (Thread t : threads) {
            t.start();
        }

        // 等待所有线程执行完成
        for (Thread t : threads) {
            t.join();
        }

        // 最终结果应该是10*100=1000
        System.out.println("Total count: " + totalCounter.get());
    }
}

额外注意事项

  • 永远不要手动实现get() + set()的递增逻辑,这会破坏原子性,导致竞态条件
  • 如果你的计数场景更复杂(比如需要先判断再更新),可以使用AtomicInteger的compareAndSet()方法来实现复合原子操作
  • 除了AtomicInteger,你也可以用synchronized块来实现线程安全计数,但AtomicInteger在高并发场景下性能更优

内容的提问来源于stack exchange,提问作者LivingRobot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:51:10