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

synchronized锁能否保证两段代码始终输出'END'?

问题1解答

没法保证程序一定输出'END'。

按Java内存模型(JMM)的规则来解释:

  • 主线程在synchronized(Visibility.class)块里把i改成1,解锁之后,这个写操作的结果只对之后拿到同一锁的操作有顺序保证。
  • 线程1里if (i == 1)的检查是在空synchronized块外面做的,读i的动作没被synchronized的内存屏障覆盖。JVM可能会优化这段代码——比如把i的值缓存到线程1自己的工作内存里,因为线程1本身没改i,JVM可能觉得i不会变,结果就是线程1永远看不到主线程写的i=1。

你本地跑总能出'END'是因为具体JVM实现或者硬件缓存的巧合,但JMM没给绝对保证。

问题2解答

这个情况能保证程序一定输出'END'。

改完之后,线程1的synchronized块里加了int x = i;,触发了关键的内存逻辑:

  • 每次进synchronized块,线程1会先加锁,JMM会强制让线程1工作内存里的共享变量(包括i)失效,读i的时候必须从主内存拿最新值。
  • 主线程改完i=1解锁后,按JMM的顺序规则,主线程的解锁操作早于线程1之后的加锁操作,所以线程1在synchronized块里读到的i肯定是主线程写的1。
  • 线程1读到i=1后,这个值会同步到自己的工作内存,下一次循环检查if (i == 1)时,直接读工作内存里的新值,就能触发输出'END'并退出循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 21:53:13