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.
相关产品推荐
相关产品推荐

