Java不遵循代码?

以下是我认为不遵循代码应该执行的代码片段:

public void updateTimeElapsed() { timeElapsedLabel.setText("Time elapsed: " + ((System.nanoTime() - time) / Math.pow(10, 9))); } public void updateTimeElapsedIndefinitely() { while (true) { //System.out.println("Hi"); //TODO: Why this no work? if (start) { System.out.println("Shoulda'"); updateTimeElapsed(); } } } 

如果我评论

 System.out.println("Hi") 

代码显然不起作用。 如果我取消注释,那就确实如此!

注意:只要按’s’开始游戏,start就为真。 但是,该方法在开始时调用,因此“hi”应该多次显示并且无限期地显示,直到我按下’s’键。

一张图片说千言万语,所以我会给你数百张图片(video)来解释我的意思: https : //dl.dropbox.com/u/2792692/CodeWeird.ogv

https://dl.dropbox.com/u/2792692/CodeWeird.wmv

谁能告诉我发生了什么事?

看起来boolean start正在被另一个线程更新,但你没有将它声明为volatile ,所以循环从不查看更新的值。

通过添加println来“修复”它只是JVM在获取控制台打印机的本机系统对象时管理线程堆栈状态的方式的一个可怕后果。 解决方法是启动volatile和/或同步访问它。

SCCE:

从不打印:

 public class Testit { public static void main(String[] args) { busted t = new busted(); t.start(); try { Thread.sleep(1000L); } catch (Exception e) {} t.startUpdating(); } public static class busted extends Thread { private boolean start = false; public void startUpdating() { start = true; } @Override public void run() { updateTimeElapsedIndefinitely(); } public void updateTimeElapsedIndefinitely() { while (true) { if (start) { System.out.println("Hello"); } } } } } 

通过更改为:1秒后开始发送垃圾邮件Hello:

private volatile boolean start = false;

我认为Affe想法是好的,但我想建议你在将来尝试使用Timer而不是while(true)循环。 至少在我看来这要好得多。