Java中Synchronized方法示例疑问:多次运行输出为何固定?
关于Synchronized示例线程执行固定的问题分析
嘿,我太懂你这种疑惑了——本来照着教程写了synchronized的多线程示例,满心期待能看到两个线程交替执行的样子,结果跑多少次输出都一模一样,连线程切换的痕迹都没看到,对吧?别担心,这不是你代码写错了,是JVM的线程调度在搞事情。
为什么输出固定?
首先,synchronized关键字确实保证了你的add方法是原子性的,不会出现多个线程同时修改value的竞态问题。但它不保证线程的执行顺序。当你启动两个线程后,JVM的线程调度器可能会让其中一个线程优先获取锁,并且一直持有锁直到它完成所有循环迭代。尤其是当循环次数比较少的时候(比如你说的最终要到90,大概率每个线程只循环45次),线程可能在调度器来得及切换到另一个线程之前,就已经跑完所有任务了。所以你看到的就是一个线程先执行完所有操作,再轮到另一个,输出自然每次都固定。
怎么看到线程交替执行的效果?
你可以试试这两个小技巧,就能验证线程切换的情况了:
- 增加循环次数:把每个线程的循环次数改成1000次甚至更多。这样单个线程很难一次性跑完所有迭代,调度器会更频繁地切换线程,你就能看到两个线程交替输出的日志了。
- 主动让出CPU:在
synchronized方法的每次操作后,加上Thread.yield()。这个方法会让当前线程主动放弃CPU使用权,给其他线程获取锁的机会,强制触发线程切换。修改后的代码片段大概是这样:
public synchronized void add(int i) { value += i; Thread.yield(); // 主动让出CPU,给其他线程机会 }
关于最终value的正确性
不管线程是交替执行还是一个先跑完另一个再跑,只要你的方法是synchronized修饰的,最终value的值肯定是符合预期的90——因为原子性保证了每次修改都是完整的,不会出现数值错乱的情况。你可以多检查几次最终结果,应该都是正确的,只是执行顺序被调度器固定了而已。
内容的提问来源于stack exchange,提问作者somerandomguy
相关产品推荐
相关产品推荐

