我在某处读到x86处理器具有缓存一致性,并且可以在每次写入时同步多个内核的字段值。
这是否意味着如果我们计划仅在x86处理器上运行,我们可以在不使用java中的'volatile'keywoard的情况下进行编码?
更新:
好的,假设我们忽略了指令重新排序的问题,我们是否可以假设在x86处理器上不存在对核心不可见的非易失性字段的分配问题?
答案 0 :(得分:6)
不 - volatile
关键字比缓存一致性具有更多含义;它还限制了运行时可以做什么和不能做什么,比如延迟构造函数调用。
答案 1 :(得分:5)
关于您的更新:不,我们不能。其他线程可以在不更新变量的情况下读取陈旧值。另一个问题是:只要能够保证单线程行为是正确的,JVM就可以优化代码。
这意味着:
public boolean var = true;
private void test() {
while (var) {
// do something without changing var
}
}
可以通过JIT优化到while(true),如果它想要的话!
答案 2 :(得分:3)
can sync the value of fields
和always syncs the value of fields
之间存在很大差异。如果你有易失性,x86可以同步字段,否则它不会也不应该。
注意:易失性访问可能比非易失性访问慢10-30倍,这是不能一直进行的关键原因。
BTW:你知道任何多核的普通x86处理器吗?我原以为大多数都是支持x86的x64。答案 3 :(得分:2)
关于JVM应该如何对volatile
采取行动有非常确切的规范,如果它选择使用特定于cpu的指令来做,那么对你有好处。
唯一可以说“我们知道在这个平台上cpu表现得像......”的地方是在本地代码中链接它需要符合cpu的时候。在所有其他情况下写入规范。
请注意,volatile关键字对于编写在多个cpu上运行的健壮代码非常重要,每个cpu都有自己的缓存,因为它告诉JVM忽略本地缓存并从5分钟前获取官方值而不是缓存值。你通常想要那个。
答案 4 :(得分:2)
字节码写入甚至不必导致机器代码写入。除非这是一个不稳定的写作。
答案 5 :(得分:1)
我可以保证volatile
有一些用处。我一直处于这样的情况,其中一个线程对于变量具有'null'而另一个线程具有在该线程中设置的变量的适当值。调试并不好玩。对所有共享字段使用volatile:)