首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锁获取时的内存可见性

锁获取时的内存可见性
EN

Stack Overflow用户
提问于 2013-06-22 22:38:16
回答 2查看 506关注 0票数 2

内存可见性是否取决于所使用的监视器?锁B是在锁A被释放后获得的,它足够内存可见性吗?

例如,以下代码:

代码语言:javascript
复制
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/

代码语言:javascript
复制
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中不可见。

此外,他们说,监测应该是相同的,但这并不是暗示从上述声明。

代码语言:javascript
复制
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. 

似乎本地内存刷新的过程并不像第一条语句所描述的那么简单,而且可能不会发生在每个锁释放上?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-22 22:50:17

是的,视情况而定。你可以读到这方面的文档。相关章节为"17.4.4.同步顺序“:

监视器m上的解锁操作同步-与m上的所有后续锁操作同步(其中“后继”根据同步顺序定义)。

您看,这里指定了一个具体的监视器对象m。如果监视器是不同的,那么在关系之前(从17.4.5开始)不会得到同步(与关系,因此不会发生):

如果一个动作x与以下动作y同步,那么我们也有hb(x,y)。

因此,您的更新将按顺序执行,可能会丢失更新。

票数 3
EN

Stack Overflow用户

发布于 2013-06-22 23:03:58

内存可见性是否取决于使用哪个监视器?是.

锁B是在锁A释放后获得的,对内存可见性是否足够?No.

这两个线程必须在同一个监视器上同步,才能看到对方的写操作。在您的示例中,两个线程都可以看到state具有1值。不管你插入什么睡眠间隔。当然,这取决于您正在使用的JVM的实现,不同的JVM可能产生不同的结果。基本上,您可以不同步地访问某个字段,应该始终避免这种情况(因为state的值不是确定性的)。

阅读更多关于记忆模型规范中关于Java的优秀章节。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17255985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档