java jvm是否保证在切换线程后更新处理器缓存?
采访者问我,如果我们确信线程永远不会干扰,那么不使用volatile
有什么危险吗
我们有:
int i = 10;
// Thread 1
i++;
// await some time and switch to Thread 2
getI();
我不使用任何同步
通过第二个线程接收过期的i
值有危险吗
你可以在下面搜索框中键入要查询的问题!
采访者问我,如果我们确信线程永远不会干扰,那么不使用volatile
有什么危险吗
我们有:
int i = 10;
// Thread 1
i++;
// await some time and switch to Thread 2
getI();
我不使用任何同步
通过第二个线程接收过期的i
值有危险吗
# 1 楼答案
如果面试官问我这个问题,我会用Java语言规范来回答。JLS中没有“缓存”或“主内存”。JLS讨论了字段(又称实例变量和类变量),并对线程a中发生的字段更新何时在线程B中可见做出了非常具体的保证。实现细节,如“缓存”和“内存障碍”,可能因平台而异,但是一个关于JLS的正确程序(理论上)应该在任何Java平台上都是正确的
# 2 楼答案
如果没有
volatile
或synchronized
或读/写屏障,就无法保证另一个线程会看到您所做的更改,无论您等待多长时间。特别是boolean
字段可以内联到代码中,实际上不执行读取。理论上,如果JVM检测到该字段没有被线程更改,那么int
值可以被内联(但我不相信它真的会更改)这不是你能知道的,除非你执行更新时阅读线程没有运行。当线程启动时,它将看到在启动之前发生的任何更改
# 3 楼答案
您可能会收到过时的值,是的
简而言之,原因是:
Java中的每个线程都有自己的小“缓存”。出于性能原因,线程在自己的内存中保留“主”数据的副本。所以你基本上有一个主内存和一个本地内存。volatile关键字强制线程访问主内存,而不是其本地内存
有关更多信息,请参阅以下内容:http://www.ibm.com/developerworks/library/j-5things15/