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

Java 多線程打造響應式用戶界面:從 Counter1 到 Counter2 的演進

     編輯:Java 相關知識

在開發圖形用戶界面(GUI)應用程式時,最常見的痛點莫過於「界面凍結」。當主執行緒被長時間運算佔用時,使用者點擊按鈕、拖動視窗都不會有任何反應。本文將透過 Counter1 與 Counter2 兩個經典範例,示範如何引入多線程機制,讓介面保持流暢響應。

問題現場:Counter1 的死結

Counter1 直接在事件處理器 actionPerformed() 中呼叫 go() 方法,後者包含一個無限迴圈:

public void go() {
    while (true) {
        try { Thread.currentThread().sleep(100); }
        catch (InterruptedException e) {}
        if (runFlag) t.setText(Integer.toString(count++));
    }
}

因為 go() 永不返回,事件派發執行緒(EDT)被永久阻塞,「Start」按鈕一按下去,整個程式就卡死,唯有強制終止進程。

解決之道:將耗時任務移交給獨立執行緒

Counter2 的核心改動是建立 SeparateSubTask 類別繼承 Thread,把原本在 go() 裡的迴圈搬進 run():

class SeparateSubTask extends Thread {
    private int count = 0;
    private Counter2 c2;
    private boolean runFlag = true;

    public SeparateSubTask(Counter2 c2) {
        this.c2 = c2;
        start(); // 啟動執行緒
    }

    public void invertFlag() { runFlag = !runFlag; }

    public void run() {
        while (true) {
            try { sleep(100); }
            catch (InterruptedException e) {}
            if (runFlag) c2.t.setText(Integer.toString(count++));
        }
    }
}

事件處理器只需 new SeparateSubTask(this) 即可瞬間返回,EDT 繼續服務其他事件,「Toggle」按鈕透過 invertFlag() 即時控制計數器啟停。

進階優化:內部類消除樣板碼

SeparateSubTask 與 Counter2 緊密耦合,必須持有外部類引用才能存取 TextField。利用 私有內部類 可自動捕獲外部實例,程式碼大幅簡化:

private class SeparateSubTask extends Thread {
    int count = 0;
    boolean runFlag = true;
    SeparateSubTask() { start(); }
    public void run() {
        while (true) {
            try { sleep(100); }
            catch (InterruptedException e) {}
            if (runFlag) t.setText(Integer.toString(count++)); // 直接存取外部 t
        }
    }
}
  • 無需手動傳遞 Counter2 參考
  • 外部 TextField t 可改為 private,封裝性更佳
  • invertFlag() 省略,直接 sp.runFlag = !sp.runFlag

關鍵觀念總結

  1. 事件派發執行緒(EDT)不可阻塞:所有 AWT/Swing 事件處理都在 EDT 執行,長時間運算必須移至背景執行緒。
  2. 執行緒間通訊靠共享旗標:runFlag 以 volatile 或同步機制保證可見性(範例為簡化省略)。
  3. 內部類是「緊密協作類」的最佳實踐:自動擁有外部實例引用,減少建構子參數、提升可讀性。

掌握這樣「EDT 輕量化 + 背景執行緒重運算」的模式,即可打造流暢不卡頓的 Java 桌面應用。

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