首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Swing 多線程實戰:讓界面保持響應的正確姿勢

     編輯:Java 程式設計入門

問題場景:長時間任務阻塞 EDT

在事件監聽器中直接執行耗時循環(如 while(true){ sleep(100); ... })會佔用 EDT,導致界面凍結、重繪停止、用戶操作無響應。

錯誤示範:在 EDT 中執行阻塞循環

void startButton_actionPerformed(ActionEvent e) {
    while (true) {
        try { Thread.currentThread().sleep(100); } catch (InterruptedException er) {}
        if (flagTrue) System.out.println("this is a test!");
    }
}

後果: 點擊「Start」後,整個視窗無法移動、最小化、關閉,「Stop」按鈕點擊無效,因為 EDT 被死循環佔用,無法處理任何事件(含繪圖與鼠標點擊)。

正確示範:使用獨立工作線程

void startButton_actionPerformed(ActionEvent e) {
    if (thread != null) thread.stop(); // 注意:stop() 已棄用,現代應用用 interrupt/標誌位
    thread = new MyThread();
    thread.start();
}

private class MyThread extends Thread {
    public void run() {
        while (true) {
            try { sleep(100); } catch (InterruptedException e) {}
            System.out.println("this is a test!");
        }
    }
}

效果: 耗時循環在獨立線程運行,EDT 釋放處理繪圖、用戶交互,界面流暢響應,「Stop」按鈕可正常終止線程。

核心原則總結

  1. EDT 只做快速 UI 操作: 事件處理、繪圖、模型小更新。
  2. 耗時任務(計算、I/O、網絡)必須移出 EDT: 使用 Thread、SwingWorker、ExecutorService 等。
  3. 跨線程更新 UI 必須回 EDT: 用 SwingUtilities.invokeLater() 或 invokeAndWait()。
  4. 避免使用已棄用的 Thread.stop(): 採用 interrupt() + 標誌位優雅終止。

「假如你能避免使用線程,最好這樣做。線程可能難於使用,並使得程序的 debug 更困難。一般來說,對於嚴格意義上的 GUI 工作,線程是不必要的。」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved