2010-12-19 59 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