如果我们确信线程永远不会干扰,面试官会问我是否存在使用volatile
的危险。
例如。我们有:
int i = 10;
// Thread 1
i++;
// await some time and switch to Thread 2
getI();
我没有使用任何同步
我们是否有可能通过第二线程接收i
的过期值?
答案 0 :(得分:4)
如果没有volatile
或synchronized
或读/写屏障,无论您的等待时间长短,都无法保证其他线程会看到您所做的更改。特别是boolean
字段可以内联到代码中,并且不会实际执行读取。从理论上讲,如果JVM检测到该字段没有被线程更改,则可以内联int
值(我不相信它确实存在)
我们确信线程永远不会干涉。
除非执行更新时读取线程未运行,否则这不是您可以知道的。当线程启动时,它将看到在启动之前发生的任何更改。
答案 1 :(得分:1)
您可能会收到过期的值,是的。
原因很简单:
Java中的每个线程都有自己的小缓存'。出于性能原因,线程会保留' master'数据在自己的记忆中。所以你基本上有一个主内存和一个threadlocal。 volatile关键字强制线程访问主内存而不是本地内存。
有关详细信息,请参阅此处:http://www.ibm.com/developerworks/library/j-5things15/
答案 2 :(得分:1)
如果面试官问我这个问题,我会回答Java语言规范。 JLS中没有“缓存”或“主内存”。 JLS讨论了字段(又名实例变量和类变量),它对发生的字段更新时做了非常具体的保证在线程A中将显示线程A中的实现细节,例如“缓存”和“内存障碍”,并且可以在不同平台之间变化,但是对于JLS而言正确的程序应该(理论上)在任何平台上都是正确的Java平台。