Java 海森堡:线程不';Don’没有系统输出就不能运行

Java 海森堡:线程不';Don’没有系统输出就不能运行,java,multithreading,Java,Multithreading,在编写一个简单的游戏时,我遇到过奇怪的行为。基本上,我创建了一个无限循环的线程,每隔几秒钟在游戏中触发一个事件。有了Sysout(runAnimation),一切都很好。然而,一旦我删除它,甚至停止发生 似乎system.out calll正在影响程序的行为,有人知道为什么会发生这种情况吗 以下是循环: private void run(){ long lastTime = -1; while(true){ int

在编写一个简单的游戏时,我遇到过奇怪的行为。基本上,我创建了一个无限循环的线程,每隔几秒钟在游戏中触发一个事件。有了Sysout(runAnimation),一切都很好。然而,一旦我删除它,甚至停止发生

似乎system.out calll正在影响程序的行为,有人知道为什么会发生这种情况吗

以下是循环:

private void run(){
            long lastTime = -1;
            while(true){
                int timePerStep = (int) Math.ceil(ANIM_TIME/frequency);
                System.out.println(runAnimation);
                if(runAnimation && System.currentTimeMillis() - lastTime > timePerStep){
                    lastTime = System.currentTimeMillis();
                    controller.step();
                    try {
                        Thread.sleep(timePerStep);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
    }
在我的班级建设过程中,开始了如下工作:

animThread = new Thread(new Runnable() {
            @Override
            public void run() {
                GUIView.this.run();
            }
        });
animThread.start();

System.out.println()
调用是
synchronized
(大多数
PrintWriter
方法调用都是)因此我怀疑代码内部有一些东西没有同步。我想知道
runAnimation
字段。这可能是在另一个线程中设置的吗?也许它需要是易变的?在一个线程中修改并在另一个线程中读取的任何字段都需要进行
同步
易失性
。阅读这本书可能会有所帮助

如果看不到更多的代码,就很难找到答案,但我怀疑这个答案无论如何都会有帮助


最后,您真的希望线程旋转直到
runAnimation
true
?那是一种非常糟糕的做法。如果
runAnimation
也是
false
的话,也许你应该在循环中睡一段时间。另一种方法是使用
倒计时闩锁
或其他信号机制暂停线程,直到它需要执行动画。

系统.out.println()调用是
同步的(大多数
PrintWriter
方法调用是)因此,我怀疑代码内部有一些东西没有同步。我想知道
runAnimation
字段。这可能是在另一个线程中设置的吗?也许它需要是易变的
?在一个线程中修改并在另一个线程中读取的任何字段都需要进行
同步
易失性
。阅读这本书可能会有所帮助

如果看不到更多的代码,就很难找到答案,但我怀疑这个答案无论如何都会有帮助


最后,您真的希望线程旋转直到
runAnimation
true
?那是一种非常糟糕的做法。如果
runAnimation
也是
false
的话,也许你应该在循环中睡一段时间。另一种方法是使用
倒计时闩锁
或其他信号机制暂停线程,直到它需要执行动画为止。

如果您的字段不是易失性的,JIT可以假定它不会更改,并将其放入寄存器中,甚至将其内联到代码中。在这个紧密循环中放置系统调用可以

  • 防止JIT以这种方式优化代码,因为它无法假设线程是否修改字段
  • 减慢循环速度,使其不会运行10000次(这是JIT开始的时间点)

关于更多细节,这里是我写的一篇关于这个主题的文章

如果您的字段不是易变的,JIT可以假定它不会改变,并将其放入寄存器,甚至将其内联到代码中。在这个紧密循环中放置系统调用可以

  • 防止JIT以这种方式优化代码,因为它无法假设线程是否修改字段
  • 减慢循环速度,使其不会运行10000次(这是JIT开始的时间点)
更多细节,这里是我写的一篇关于这个主题的文章