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

Java8 AtomicInteger线程示例运行异常:输出值不稳定求助

问题分析与解决

嘿,我来帮你捋清楚这个问题~你遇到的输出不一致的情况,根本原因不是AtomicInteger的线程安全问题,而是你用错了线程池的关闭方法!

问题出在哪?

你代码里用了executor.shutdownNow(),这个方法的作用是:

  • 立即尝试终止所有正在执行的任务
  • 暂停处理所有等待中的任务
  • 返回那些还没来得及执行的任务列表

也就是说,你的1000个任务还没全部执行完,线程池就被强制关停了,自然每次运行时实际完成的任务数量都不一样,输出结果也就波动了。而AtomicInteger本身的updateAndGet()方法确实是线程安全的,只要任务全部执行,结果肯定是2000。

正确的写法应该是这样

把shutdownNow()换成shutdown()(这个方法会让线程池不再接受新任务,等待已提交的任务全部执行完毕),然后调用awaitTermination()来等待所有任务完成,确保结果正确:

public class Test_AtomicInteger {
    public static void main(String[] args) throws InterruptedException {
        AtomicInteger atomicInt = new AtomicInteger(0);
        ExecutorService executor = Executors.newFixedThreadPool(2);
        
        IntStream.range(0, 1000)
            .forEach(i -> {
                Runnable task = () -> atomicInt.updateAndGet(n -> n + 2);
                executor.submit(task);
            });
        
        executor.shutdown(); // 不再接受新任务,等待已提交任务完成
        // 等待最多10秒,直到所有任务执行完毕
        if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
            // 如果超时还没完成,再强制关停(可选)
            executor.shutdownNow();
        }
        
        System.out.println(atomicInt.get()); // 现在稳定输出2000
    }
}

补充说明

  • shutdown()是优雅关闭,而shutdownNow()是强制关闭,在需要等待任务全部完成的场景下,一定要用前者配合awaitTermination()。
  • AtomicInteger的原子操作是可靠的,这个案例里的线程安全问题完全是线程池关闭时机不对导致的。

内容的提问来源于stack exchange,提问作者Patrick C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:06:04