您对术语“第一个线程”和“第二个线程”的定义有些过分;您的问题预设了进入第一个synchronized
块的第一个线程也将是进入第二个synchronized
块的第一个线程,但实际上没有理由期待这一点。
然而,第一个synchronized
块并没有做任何非常相关或有趣的事情——你的代码片段中没有任何东西 mutates k
,第一个synchronized
块只是访问它——所以我将忽略它是synchronized
. 这将稍微简化定义:现在“第一个线程”表示进入第二个synchronized
块的第一个线程,“第二个线程”表示进入第二个synchronized
块的第二个线程。(到目前为止还好吗?) 定义的问题。. .
假设不可能有其他线程进入并设置x.b
为true
- 或者,就此而言,第一个线程这样做,在您引用的代码段之后的代码中 - 同样,两个线程不可能完全不同结果是k.get("LL")
由于其他地方发生的事情 - 然后第二个线程将x.b
显示为false
,就像人们天真地期望的那样。这是因为
如果一个动作发生在另一个动作之前,那么第一个动作对第二个动作可见并在第二个动作之前排序。
和
监视器上的解锁发生在该监视器上的每个后续锁定之前。
(以上两个引文均来自Java 语言规范,Java SE 7 版的第 17.5.5节;有关更多形式,请参见该部分及其之前的部分。)