我遇到了一个在运行Java 8时可以创建的一个相当奇怪的问题.问题表现在JVM本身内部发生了某种时序错误.它本质上是间歇性的,但很容易重现(至少在我的测试环境中).问题是显式设置的数组值在某些情况下被销毁并替换为0.0.具体来说,在下面的代码中,array[0]在行之后评估为0.0 new Double(r.nextDouble());.然后,如果您立即array[0]再次查看其内容,它现在会将该值显示为正确的值1.0.运行此测试用例的示例输出是:
claims array[0] != 1.0....array[0] = 1.0
claims array[0] now == 1.0...array[0] = 1.0`
Run Code Online (Sandbox Code Playgroud)
我正在运行64位Windows 7,并且能够从Eclipse中以及从命令行编译时使用JDK 1.8_45,1.8_51和1.8_60重现此问题.我无法解决运行1.7_51的问题.在另一个64位Windows 7机箱上演示了相同的结果.
这个问题出现在一个大型的,非平凡的软件中,但我已经设法将其浓缩为几行代码.下面是一个小问题,用于演示此问题.这是一个相当奇怪的测试用例,但似乎都有必要导致错误.使用Random不是必需的 - 我可以r.nextDouble()用任何双重值替换所有并证明问题.有趣的是,如果someArray[0] = .45;被替换someArray[0] = r.nextDouble();,我无法复制问题(虽然没有什么特别的.45).Eclipse调试也没有任何帮助 - 它会改变时间,使其不再发生.即使是陈述良好的System.err.println()声明也会导致问题不再出现.
同样,问题是间歇性的,因此要重现问题,可能需要多次运行此测试用例.我认为在获得上面显示的输出之前,我必须运行它的次数大约是10次.在Eclipse中,我在运行后给它一两秒,然后在没有发生时将其杀死.从命令行开始 - 运行它,如果它没有发生CTRL+C退出并再试一次.似乎如果它会发生,它会很快发生.
我在过去遇到过这样的问题,但它们都是线程问题.我无法弄清楚这里发生了什么 - 我甚至看过字节码(顺便说一下,1.7_51和1.8_45之间是相同的).
关于这里发生了什么的任何想法?
import java.util.Random;
public class Test {
Test(){
double array[] = new double[1];
Random r = new Random();
while(true){
double someArray[] = new double[1];
double …Run Code Online (Sandbox Code Playgroud)