在Linux中运行Java不会有一段时间

我发现一个Java代码作业的神秘问题。 一个朋友编程这个开头的应用程序:

public void run() { vm.setVisible(true); while(!end); System.out.println("Finish"); vm.setVisible(false); } 

当所有执行和用户退出应用程序时,布尔“结束”都是假的:

 private class CloseSys implements ActionListener { public CloseSys() {super();} public void actionPerformed(ActionEvent e) { System.out.println("CLOSE SYS"); System.out.println("end: "+end); end = true; System.out.println("end: "+end); } } 

println在完成和应用程序中显示像'end'的值在我的朋友的计算机(MacOS)中真实和逻辑地转换。

问题是,在我的电脑(Ubuntu的Linux)的println也显示像价值的变化,但一段时间没有结束(“完成”println永远不会到达)。 有趣的是,如果我们把印刷品放在一边…然后工作!

end必须是volatile因为它在两个线程之间共享!

其他几个人提到它应该是不稳定的。 有一点似乎没有人提到,就是你“忙着等待”,这是错的,错的,错的错。 如果你想等待另一个线程发生什么事情,你应该使用同步锁或信号量 。

尽量让end变量易变 – 你已经被多线程问题困扰了(并且你有一个多核CPU)。

这里有一些信息: http : //www.javamex.com/tutorials/synchronization_volatile_when.shtml

它看起来像一个线程问题。

尝试将end声明为volatile ,或者更好地使用CountDownLatch因为这可以避免占用CPU:

 private CountDownLatch latch; public void run() { try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { vm.setVisible(true); } }); try { latch.await(); System.out.println("Finish"); } finally { SwingUtilities.invokeAndWait(new Runnable() { public void run() { vm.setVisible(false); } }); } } catch (InterruptedException ex) { System.out.println("Interrupt"); Thread.currentThread().interrupt(); } catch (InvocationTargetException ex) { throw new RuntimeException(ex); } } private class CloseSys implements Actionlistner { public void actionPerformed(ActionEvent e) { System.out.println("CLOSE SYS"); latch.countDown(); } } 

请注意使用invokeAndWait来更改来自非EDT线程的窗口可见性。