Java synchronized关键字所需的缓存刷新范围是什么?

时间:2009-05-06 01:46:14

标签: java synchronization

我今天一直在研究Java内存模型,以便详细了解JMM pre-Java 5的问题以及Java 5中实现的JSR-133所做的更改。

我似乎无法找到明确的答案是特定同步所需的缓存失效和刷新范围。

在进入代码的任何同步部分并且在离开时全部刷新到主RAM时,所有CPU寄存器和高速缓存都必须无效,或者JVM是否只允许实际读取的那些变量无效,并且仅刷新在同步块期间实际写入的那些代码?

如果是前者,为什么JMM如此迂腐,坚持认为内存屏障只发生在同一个对象同步的两个线程之间?

如果是后者,是否有任何好的文件可以解释如何实现这一目标的细节? (我认为底层实现必须在同步块开始时在CPU级别设置“旁路缓存”标志并在结束时清除它,但我可能方式 off base。 )

3 个答案:

答案 0 :(得分:5)

Java Memory model上有非常好的技术讲座。如果您不喜欢在Java内存模型的上下文中使用google 'happens before'

基本上所有写入对于其他线程都是可见的,如果在关系之前发生,请假设线程A写入字段X,线程B从中读取,因此在写入和读取之间建立之前发生如下:

  • x is volatile
  • 对x的写入是由从x
  • 读取的同一个锁保护的
  • 也许还有一些。

所以我认为第二种选择是真的,他们是如何实现的,我不知道。

答案 1 :(得分:1)

您需要了解5.0之前的JMM从未真正实现过,因为它实际上并不可行。

所以在5.0之前,你在技术上必须把所有内容都写到共享内存中。 1.5(实际上是1.4)这是放松的。特别是,如果锁无法转义线程,则JVM有权将其视为nop。此外,可以合并解锁,然后锁定相同的锁,这对于旧的JMM是不正确的。对于转义锁,JVM通常必须是悲观的,并且比技术上更需要冲洗。

答案 2 :(得分:1)

我建议你从:

开始