我观察到,JVM 1.5+中不安全的对象发布不太可能造成任何麻烦,无论JVM规范如何说明不能保证这些对象在线程之间可见。
在互联网上环顾四周时,我发现了这一点:http://forum.springsource.org/archive/index.php/t-60676.html昵称为“ al0 ”的人称,“[......]不太可能遇到此类行为基于x86 / x64的计算机,但基于HP PA-RISC或基于IBM Power ...的计算机(例如AS400),它更有可能“。
x86 / x64架构是否能够抵御不安全的发布?怎么样?
答案 0 :(得分:3)
x86处理器对不安全的出版物有一定的抵抗力。特别是,只要一个线程只写入共享内存而另一个线程只读取,处理器就会将所有加载和存储视为内存位置具有Java volatile
语义。写入永远不会在写入之后重新排序,并且读取从不会在读取之后重新排序,因此读取线程始终以正确的顺序看到写入
然而:
写入可以在程序后面的读取之后移动。从这个意义上讲,volatile
仍然比x86承诺的更强大
这仅涵盖处理器可以对您的代码执行的操作。 虚拟机仍然可以按照自己的意愿重新排序代码。例如,它可以将x.b = 4; y.a = 5;
重写为y.a = 4; x.b = 5
。
这样的决定可以基于许多不同的因素:选择代码的哪些部分将被JIT编译,内联,调度......所以即使在具有强大内存排序的处理器上,不安全的发布仍然是不安全的。
答案 1 :(得分:1)
我不想推测x86 / x64 CPU上是否出现问题的可能性更大或更小。声称不太可能在x86 / x64 CPU上看到此行为错误。
Niklas Schlimm在DZone中写了一篇关于此内容的文章,其中有一个工作示例,用于演示如果具有多线程访问权限的变量未声明为volatile的错误行为。他在文章中写道,他只能重现服务器虚拟机的行为,但对我来说,测试也失败了客户端虚拟机(Oracle Java 7,英特尔x64移动CPU)。重要的是要记住,如果行为完全可再现,甚至可能只是零星的,它至少取决于Java VM和CPU模型的确切版本。