Java:为什么主线程没有进展?

Mor*_*rty 8 java multithreading

我遇到了一些多线程Java程序的问题,并将其简化为一个非常简单的例子 - 我的困惑仍然不少!

它的示例程序如下所示.那么这是做什么(或者打算做什么)?好吧,main()函数从一个简单的线程开始,基于一个静态的内部类Runnable.这个Runnable包含两个嵌套循环,它们对局部变量"z"进行简单计算,总计10 ^ 12次迭代(10 ^ 6*10 ^ 6),之后它将打印出结果并退出.产生这个工作线程后,主线程进入一个自己的循环,它将字符串"Z"打印到控制台,之后它休眠(使用Thread.sleep())1秒钟,然后反复重复.

所以运行这个程序,我希望它在计算线程正在完成它的工作时每1秒打印一次"Z".

然而,事实上发生的是计算线程启动,主线程显示第一个"Z",但没有任何反应.它似乎挂在Thread.sleep调用中,无论是无限的还是至少很多,比请求的1000毫秒长得多.

请注意,这是在具有多线程的快速四核机器上,因此同时运行线程应该没有问题.其他核心在Windows任务管理器中显示为空闲.此外,即使在单核系统上,我也希望操作系统定期抢占计算线程,以便允许主线程打印字符串.此外,线程之间没有共享变量或锁定,因此它们不应该相互阻塞.

更奇怪的是,它似乎对行为至关重要,Runnable中有两个嵌套循环.只需一个循环,迭代次数相同,一切都按预期工作.

我已经使用Java 1.8.0_73在Windows 10 64位上对此进行了测试.

有人可以解释这种行为吗?

public class Calculate {
    static class Calc implements Runnable
    {
        @Override
        public void run() {
            int z = 1;
            for(int i = 0; i < 1000000; i++) {      
                for(int j = 0; j < 1000000; j++) {
                    z = 3*z + 1;
                }               
            }
            System.out.println("Result: " + z);
        }
    }

    public static void main(String[] args)  throws Exception
    {
        Thread t = new Thread(new Calc());
        t.start();
        while(true) {
            System.out.println("Z");
            Thread.sleep(1000);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新1:有人建议这可能是其他线程延迟EDT处理Busy循环的重复.在我的情况下,许多症状是相同的,但很难说它们是否真的是同一个原因,因为另一个问题似乎没有被完全诊断出来.但这很有可能.

更新2:我已向Oracle提交了错误报告.我会发布链接,如果它被接受,我找到它.

更新3:在Java 8和9中被接受为错误:https://bugs.openjdk.java.net/browse/JDK-8152267

Mor*_*rty 0

正如我在描述中的“更新 3”中放入的那样,这被证明是 Java 8 和 9 中的一个错误。所以这是这个问题的正确答案:程序没有任何问题,行为是由Java 某些版本中的错误,导致其无法正常运行。虽然在程序中插入暂停、让出等的建议可能与寻找实际解决方法的人相关,但“缺乏这些解决方法”并不是问题的根本原因,也不代表原始程序中存在错误。