Java x86/x64体系结构是否能够抵抗不安全的发布?

Java x86/x64体系结构是否能够抵抗不安全的发布?,java,multithreading,cpu,Java,Multithreading,Cpu,我已经观察到,JVM 1.5+中对象的不安全发布不太可能引起任何问题,不管JVM规范声明不保证这些对象在线程之间可见 在互联网上四处查看时,我发现:nick“al0”的人声称“[…]在基于x86/x64的机器上不太可能出现这种行为,但在基于HP PA-RISC或IBM Power的计算机(例如AS400)上更可能出现这种行为” x86/x64体系结构是否能够抵抗不安全的发布?为什么会这样?我不想猜测问题是否或多或少会发生在x86/x64 CPU上。声称在x86/x64 CPU上不太可能出现这种行

我已经观察到,JVM 1.5+中对象的不安全发布不太可能引起任何问题,不管JVM规范声明不保证这些对象在线程之间可见

在互联网上四处查看时,我发现:nick“al0”的人声称“[…]在基于x86/x64的机器上不太可能出现这种行为,但在基于HP PA-RISC或IBM Power的计算机(例如AS400)上更可能出现这种行为”


x86/x64体系结构是否能够抵抗不安全的发布?为什么会这样?

我不想猜测问题是否或多或少会发生在x86/x64 CPU上。声称在x86/x64 CPU上不太可能出现这种行为是错误的


Niklas Schlimm在中写了一篇关于这一点的文章,并用一个工作示例演示了如果一个具有多线程访问的变量未声明为volatile,那么该变量的错误行为。他在文章中写道,他只能在服务器虚拟机上重现这种行为,但对我来说,客户端虚拟机(Oracle Java 7、Intel x64 Mobile CPU)的测试也失败了。重要的是要记住,如果行为完全是可复制的,或者甚至只是零星的,那么它至少取决于javavm的确切版本和CPU模型

x86处理器对不安全的发布有一定的抵抗力。特别是,只要一个线程只向共享内存写入,另一个线程只读取,处理器就会将所有加载和存储视为内存位置具有Java
volatile
语义。写入永远不会在写入之前重新排序,读取也永远不会在读取之前重新排序,因此读取线程总是以正确的顺序查看写入

然而:

  • 写入可以在程序中稍后进行的读取之后移动。从这个意义上讲,
    volatile
    仍然比x86承诺的更强大

  • 这仅涵盖处理器可以对代码执行的操作。虚拟机仍然可以按照自己的意愿对代码重新排序。例如,它可以重写
    x.b=4;y、 a=5
    y.a=4;x、 b=5


这样的决定可以基于许多不同的因素:选择JIT编译代码的哪些部分、内联、调度。。。因此,即使在具有强内存排序的处理器上,不安全的发布仍然是不安全的。

x86/x64具有相对强的内存排序保证,尽管我认为它实际上不能保证不安全的发布不是不安全的。好吧,这更像是“反正它可能会起作用”。