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

多线程同步后执行变量+1仍结果不一致,求正确实现及原因

问题分析与解决方案

首先可以肯定的是,你当前的同步方式是正确的:通过synchronized(add)锁住了共享的Adder实例,确保同一时间只有一个线程能执行add()方法里的count += 1操作,从根源上避免了多线程下的竞态条件问题。

那为什么结果还是达不到1000呢?核心问题出在主线程没有等待所有子线程执行完毕就打印了结果!

你看,main方法里启动完1000个线程后,立刻就执行System.out.println("----- " + adder.count);,这时候大部分线程可能还在等待获取锁,甚至还没开始执行run()方法。你看到的995-997只是主线程打印瞬间已经完成的线程数量,并不是所有1000个线程都执行完毕后的最终值。

修复方案:让主线程等待所有子线程结束

只需要在启动所有线程后,遍历线程数组,调用每个线程的join()方法,让主线程阻塞直到所有子线程都执行完成,再打印结果。修改后的Main类代码如下:

public class Main extends Thread{
    public static void main(String[] args) {
        Thread[] threads = new Thread[1000];
        Adder adder = new Adder();
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new ThreadAddSync(adder));
            threads[i].start();
        }
        
        // 新增:等待所有子线程执行完毕
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        System.out.println("----- " + adder.count);
    }
}

这样修改后,每次运行都会稳定输出1000,因为主线程会等到所有1000个线程都完成了add()操作后,才会打印count的值。

另外补充一点:你之前看到波动范围缩小,是因为同步机制让线程执行add()的过程更有序、更快,所以在主线程打印时,完成的线程数量更多,但本质上还是没等所有线程结束,所以结果依然不是预期的1000。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:59:16