【发布时间】:2013-06-22 22:38:16
【问题描述】:
内存可见性是否取决于所使用的监视器?锁B是在锁A释放后获取的,内存可见性够吗?
例如以下代码:
int state; // shared
// thread A
synchronized (A) {
state += 1;
}
Thread.sleep(10000000);
// thread B
Thread.sleep(1000);
synchronized(B) {
state += 1;
}
线程同时启动,线程B的休眠时间可以任意高,只是为了保证在线程A使用state变量之后执行。线程A 睡眠时间用于确保线程在B 使用state 共享变量之前不会完成。
更新
来自http://www.ibm.com/developerworks/library/j-jtp03304/
When a thread exits a synchronized block as part of releasing the associated monitor, the JMM requires that the local processor cache be flushed to main memory.
Similarly, as part of acquiring the monitor when entering a synchronized block, local caches are invalidated so that subsequent reads will go directly to main memory and not the local cache.
如果这是真的,那么我认为state 变量对线程B 不可见
此外,他们说监视器应该是相同的,但上述陈述并未暗示。
This process guarantees that when a variable is written by one thread during a synchronized block protected by a given monitor and read by another thread during a synchronized block protected by the same monitor, the write to the variable will be visible by the reading thread.
似乎本地内存刷新的过程并不像第一个语句中描述的那么简单,并且可能不会在每个锁释放时发生?
【问题讨论】:
-
happens-before 关系是二元的,即仅在两个事件之间。虽然它是可传递的。如果 A 发生在 B 之前,您只能从 B 获得 A 的内存可见性。
-
@selig,但
Thread.sleep是否添加了happens before关系? -
否 - 如 JLS 中的详细 here 所述,
Sleep和Yield都没有同步语义,即参与发生前的关系。
标签: java concurrency