4

我观察到,在 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 架构是否能够抵抗不安全的发布?怎么来的?

4

2 回答 2

3

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

然而:

  • 可以在程序稍后的读取之后移动写入。从这个意义上说,volatile仍然比 x86 所承诺的要强

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

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

于 2013-08-29T13:03:01.687 回答
1

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

Niklas Schlimm 在DZone中写了一篇关于此的文章,其中包含一个工作示例,以演示如果具有多线程访问的变量未声明为 volatile 时的错误行为。他在文章中写道,他只能使用服务器 VM 重现该行为,但对我来说,客户端 VM 的测试也失败了(Oracle Java 7,Intel x64 Mobile CPU)。重要的是要记住,如果行为完全可重现或什至可能只是零星的,它至少取决于 Java VM 的确切版本和 CPU 模型。

于 2013-08-29T12:57:19.500 回答