</div>
</div>
JButton button = new JButton();
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
//位置A
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//位置B
invokeRemoteService();//可能需要等待
}
});
doOtherThing();
}
});
這段代碼跟第一段代碼唯一的差別是doOtherThing()在invokeRemoteService ()完成之前就能夠得到執行,所以造成了invokeRemoteService ()/doOtherThing()好像是在兩個線程里執行的假象。
實際上invokeLater是把目標代碼打包成一個Event提交到EventQueue去了,等到EventDispatchThread線程執行完當前代碼段的doOtherThing()后,
再去執行這個EventQueue中的Event,這時候就會執行到這個invokeRemoteService ()方法。
但是,實際上這兩個方法都是在EventDispatchThread中執行的,并沒有任何其他Thread來執行。
于是,問題1的問題還是沒解決。實際上直接new Thread().start()方法就可以了,使用SwingUtilities完全是由于誤解造成的濫用。
測試方法,在位置A和位置B都加上下面這行代碼:
System.out.println(Thread.currentThread().getId() + Thread.currentThread().getName());
返回的結果都是一樣的:
21AWT-EventQueue-0
21AWT-EventQueue-0 [討論]
一般情況下(除了系統啟動時后臺創建的Daemon線程),系統的所有執行功能邏輯和業務邏輯的線程都應該是從界面操作觸發的。
我們應該清楚哪些需要或應該放到EventDispatchThread中去執行,哪些需要或應該創建一個新線程去執行,也需要清醒的知道自己當前編寫的是屬于什么邏輯。
這個問題我覺得應該把代碼分成3層,第一層,UI層,包括UI控件上的Listener邏輯,這是應該給EventDispatchThread去執行的,必須簡短高效,快速return;
這一層做不完的事情通過new Thread().start()交給下一層去做,我稱之為控制層;然后控制層再去調用具體的業務代碼,即第三層,業務層。所有由UI控件觸發的邏輯都應該這么分。
另一個問題是,Swing并不推薦在EventDispatchThread之外修改界面,那么,如果我們在業務層需要repaint某個控件,
或者updateUI應該怎么辦呢,那就可以使用SwingUtilities來處理了,這才是正確使用SwingUtilities的場景,也是設計這個工具的目的。
本文由用戶
jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!