成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Swing多線程編碼過程中的誤區

開發 后端
很多學JAVA程序員都是從Swing開始的,但很多人對AWT GUI線程的機制并沒有太深的了解,或者說一直都只了解線程的概念,而不了解AWT對線程的使用。我發現很多人碰到線程阻塞的問題,就通過調用 SwingUtilities.invokeLater()來解決。

很多學JAVA程序員都是從Swing開始的,但很多人對AWT GUI線程的機制并沒有太深的了解,或者說一直都只了解線程的概念,而不了解AWT對線程的使用。我發現很多人碰到線程阻塞的問題,就通過調用 SwingUtilities.invokeLater()來解決。

其實這是很容易造成誤會的地方:

  1. 不要以為Swing 是多線程的,實際上Swing 的UI是單線程的
  2. 不要以為SwingUtilities.的兩個invoke是多線程,實際上它還是單線程的
  3. 不要以為invokeLater的意思是當前線程執行完再執行目標線程;以為invokeAndWait的意思是等待目標線程執行完再執行當前線程,實際上壓根就不是那么回事

問題代碼1:大意是在按下某個按鈕的時候調用一個遠程服務

  1. JButton button = new JButton();   
  2. button.addActionListener(new ActionListener(){   
  3. @Override   
  4. public void actionPerformed(ActionEvent e) {   
  5. invokeRemoteService();//可能需要等待   
  6. }   
  7. });  

在swing系統中,有一個頂級的java.awt.Container(可能是一個JFrame或JDialog實例),負責啟動一個EventDispatchThread線程,單線程,這個線程是負責處理UI事件的。

首先,界面Swing控件向EventDispatchThread的EventQueue提交一個event,由 EventDispatchThread負責調度各個event的執行。例如,按下一個JButton的時候,JButton向EventQueue執行 postEvent,提交一個ActionEvent。EventDispatchThread線程根據調度算法執行到該event的時候,會調用 JButton上的processActionEvent,JButton再調用actionPerformed,這過程并沒有執行任何new Thread().start()代碼,也就是說JButton的ActionListener.actionPerformed()中的代碼完全是在 EventDispatchThread線程內執行的。

所以,假如我們在任何ActionListener、MouseListener等對象中編寫耗時的邏輯,那么整個Swing系統就會出現響應遲鈍的現象,更有甚者,如果在這些Listener中執行線程wait(),以等待另一個線程的鎖定資源或計算結果,那么實際上就是 EventDispatchThread線程被阻塞,整個系統界面就會處于無響應狀態,一點反應都沒有。

以上是誤解1造成的,了解這個過程,就很容易看出上面這段代碼的問題是什么原因了。解決的方法也倒比較簡單,直接new Thread().start();就可以保證EventDispatchThread執行到當前方法的時候快速返回,以便可以去響應來自用戶界面的其他事件。

問題代碼2:大意是在按下某個按鈕的時候調用一個遠程服務,同時處理其他事情

  1. JButton button = new JButton();   
  2. button.addActionListener(new ActionListener(){   
  3. @Override   
  4. public void actionPerformed(ActionEvent e) {   
  5. //位置A   
  6. SwingUtilities.invokeLater(new Runnable() {   
  7.      public void run() {   
  8. //位置B   
  9.          invokeRemoteService();//可能需要等待   
  10.      }   
  11. });   
  12. doOtherThing();   
  13. }   
  14. });  

這段代碼跟第一段代碼唯一的差別是doOtherThing()在invokeRemoteService ()完成之前就能夠得到執行,所以造成了invokeRemoteService ()/doOtherThing()好像是在兩個線程里執行的假象。實際上invokeLater是把目標代碼打包成一個Event提交到 EventQueue去了,等到EventDispatchThread線程執行完當前代碼段的doOtherThing()后,再去執行這個 EventQueue中的Event,這時候就會執行到這個invokeRemoteService ()方法。但是,實際上這兩個方法都是在EventDispatchThread中執行的,并沒有任何其他Thread來執行。于是,問題1的問題還是沒解決。實際上直接new Thread().start()方法就可以了,使用SwingUtilities完全是由于誤解造成的濫用。

測試方法,在位置A和位置B都加上下面這行代碼:

  1. 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的場景,也是設計這個工具的目的。

原文鏈接:http://seaman.iteye.com/blog/608584

【編輯推薦】

  1. 控件位置可以配置的Swing桌面
  2. Swing特效:漸顯效果
  3. 簡述Java圖形用戶界面設計(Swing)
  4. 用Swing制作精美的圖層疊加圖
  5. 簡述Java圖形用戶界面設計(Swing)
責任編輯:林師授 來源: seaman的博客
相關推薦

2011-05-03 10:31:59

噴墨打印機注墨誤區

2012-06-14 08:46:03

IDC云計算

2010-09-13 10:00:51

CSS注釋

2009-05-15 09:33:52

開發線程沖突lock

2009-07-16 08:53:03

Swing任務Swing線程

2009-07-16 09:54:44

LookupEventSwing線程

2010-05-24 14:04:48

JavaSwing多線程

2009-07-16 09:28:37

軟件開發過程

2009-07-14 15:34:22

Swing中的線程GUI程序

2009-04-30 09:10:42

JavaSwing線程安全

2022-09-06 08:25:13

線程異步任務

2009-07-23 14:10:38

Hibernate J

2013-08-15 12:26:40

阿里云飛天

2010-07-01 14:05:43

SNMPMIB

2011-04-11 17:28:50

oracle存儲select語句

2025-06-25 09:06:18

2022-03-07 07:57:04

Linux工具內存

2010-04-15 16:54:31

Oracle存儲過程

2010-05-31 16:57:09

2019-08-13 15:01:04

變更運維項目經理
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91成人在线视频 | 国产午夜精品视频 | 亚洲中午字幕 | 免费一区二区三区 | 成人免费视频网站在线观看 | 风间由美一区二区三区在线观看 | h视频在线观看免费 | 国产视频二区 | 欧美精品a∨在线观看不卡 欧美日韩中文字幕在线播放 | 国产一区二区三区视频在线观看 | 欧美日韩一卡二卡 | 亚州国产| 欧美一级淫片免费视频黄 | 免费一区二区三区 | 999精品视频在线观看 | 黄色大片视频 | 国产欧美一区二区三区日本久久久 | 中文字幕亚洲欧美日韩在线不卡 | av在线一区二区三区 | 一级做a爰片性色毛片视频停止 | 欧美一区二区三区视频 | 久久精品视频一区二区三区 | 亚洲一区自拍 | 日批免费观看 | 亚洲色欧美另类 | 国产视频久久久 | 国产成人精品免高潮在线观看 | 国产第一亚洲 | 九九在线视频 | 97色在线视频 | 国产精品美女www爽爽爽 | 在线成人 | 亚洲欧洲一区二区 | 久久亚洲天堂 | 综合久久99 | 日韩成人免费视频 | 国产一区二区激情视频 | 五月婷婷激情网 | 精品久久久久国产 | 午夜精品一区二区三区在线观看 | 久久久91精品国产一区二区三区 |