多线程同步后执行变量+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
相关产品推荐
相关产品推荐

