2010-12-19 73 views
6

我发现了一个Java代码用于作业的神秘问题。一个朋友程序的应用程序,这个开头:Java在Linux中运行时没有中断一段时间

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的节目,如在我的朋友的电脑(MacOS)中完成和应用程序的'end'值变为真实和逻辑。

问题是,在我的电脑(Ubuntu Linux)中,println也显示值变化,但while不会结束(“Finish”println永远不会到达)。有趣的是,如果我们把印刷品放在一边......然后工作!

+4

请注意,您不应该在AWT事件派发线程(EDT)中使用Swing(或在实践中使用AWT)。 – 2010-12-19 15:27:54

回答

3

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

+0

谢谢,这解决了问题:)我标记你解决,因为我认为你是第一个答案。我不知道是否这样做。 – davidgnin 2010-12-19 15:56:52

+0

我第一次约17秒,但这是公平的;-) – Lucero 2010-12-19 16:09:01

+0

:)是的!我赢了! :) – dacwe 2010-12-19 16:42:13

2

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

尝试宣告endvolatile,或者更好的是使用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 ActionListener {  
    public void actionPerformed(ActionEvent e) { 
     System.out.println("CLOSE SYS"); 
     latch.countDown(); 
    } 
} 

注意使用invokeAndWait从非EDT线程改变窗口的可见性。

+0

为什么需要一个CountDownLatch?为什么不只是Object.wait()? – 2010-12-19 15:51:41

+0

易变的作品,不幸的是我现在没有时间去尝试CountDownLatch,但我会尽快尝试。 – davidgnin 2010-12-19 15:54:50

+0

@Sergey Tachenov,'Object.wait'是一个低层次的方法,有缺陷,例如, '通知' - 对''nototallAll',虚假唤醒。你可以解决它,但你会重新发明轮子。 – finnw 2010-12-20 13:08:47

5

其他人已经提到它应该是不稳定的。有一件事似乎没有人提到过,就是你“忙着等待”,这是错误的,错误的,错误的错误。如果您想等待另一个线程中发生某些事情,则应使用同步锁或Semaphores

+0

+1 - 好点。 – Lucero 2010-12-19 16:10:01