2013-10-03 52 views
3

我最近發現的示例代碼:爲什麼使用invokeLater很重要?

public static void main(String[] args) { 
    javax.swing.SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGUI(); 
     } 
    }); 
} 

createAndShowGUI()方法打開的用戶界面窗口。然後,我試圖修剪代碼,如下所示:

public static void main(String[] args) { 
    createAndShowGUI(); 
} 

兩個版本的效果都很好。有什麼不同?

+1

它在大多數情況下運行良好,但偶爾您的GUI線程和更新GUI的線程將導致奇怪且不可重複的行爲。這是測試多線程代碼時遇到的問題,您可以在幾天內運行它並更改較小的內容,並且突然顯示它經常出現。 –

+0

可能的重複http://stackoverflow.com/questions/6567870/what-does-swingutilities-invokelater-do – Masudul

回答

10

99%的時間或代碼將工作。

但是,Swing的設計使得Swing組件的所有更新都應在事件調度線程(EDT)上完成。有關更多信息,請閱讀有關Concurrency的Swing教程。

問題是1%的時候它可能無法正常工作。你不想浪費時間試圖調試隨機問題。

4

SwingUtilities.invokeLater確保代碼在事件調度線程(EDT)上執行。 Swing是單線程的,所有組件實例化和顯示應該在EDT上進行。事情似乎可以起作用,但是你可能會遇到問題。

3

Swing具有基於單線程事件循環的設計,並且不是線程安全的,只有線程安全部分是用於將控制權交給Swing事件循環的一組invokeXXX()方法。

您的「破損」代碼工作得很好,因爲沒有其他任何嘗試同時觸碰Event Loop中同一部分的Swing數據結構。

3

JVM啓動的「主」線程不是事件派發線程。

The Event Dispatch Thread

一些Swing組件的方法中的API規範被標爲 「線程安全」;這些可以從任何線程安全地調用。 必須從事件分派線程調用​​所有其他Swing組件方法。忽略此規則的程序可能在大多數情況下都能正常運行,但會遇到難以重現的不可預知的錯誤。

相關問題