内存可见性是否取决于所使用的监视器?锁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. 似乎本地内存刷新的过程并不像第一条语句所描述的那么简单,而且可能不会发生在每个锁释放上?
发布于 2013-06-22 22:50:17
是的,视情况而定。你可以读到这方面的文档。相关章节为"17.4.4.同步顺序“:
监视器m上的解锁操作同步-与m上的所有后续锁操作同步(其中“后继”根据同步顺序定义)。
您看,这里指定了一个具体的监视器对象m。如果监视器是不同的,那么在关系之前(从17.4.5开始)不会得到同步(与关系,因此不会发生):
如果一个动作x与以下动作y同步,那么我们也有hb(x,y)。
因此,您的更新将按顺序执行,可能会丢失更新。
发布于 2013-06-22 23:03:58
内存可见性是否取决于使用哪个监视器?是.
锁B是在锁A释放后获得的,对内存可见性是否足够?No.
这两个线程必须在同一个监视器上同步,才能看到对方的写操作。在您的示例中,两个线程都可以看到state具有1值。不管你插入什么睡眠间隔。当然,这取决于您正在使用的JVM的实现,不同的JVM可能产生不同的结果。基本上,您可以不同步地访问某个字段,应该始终避免这种情况(因为state的值不是确定性的)。
阅读更多关于记忆模型规范中关于Java的优秀章节。
https://stackoverflow.com/questions/17255985
复制相似问题