首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 多線程入門:為什麼點擊 Start 後 Stop 按鈕失效?

     編輯:程式設計綜合問答

錯誤代碼分析

初學者編寫的雙按鈕控制台打印程序,點擊 Start 後界面凍結,Stop 無響應。核心代碼片段:

class B1 extends Thread {
    public void run() {
        b1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                while(flag) { System.out.println("start"); }
            }
        });
    }
}
class B2 extends Thread {
    public void run() {
        b2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) { flag = false; }
        });
    }
}

根本原因

  1. 線程模型錯誤:在線程 B1 的 run() 中註冊監聽器,線程啟動後立即結束,監聽器實際運行在 事件分發線程 (EDT) 中,而非新線程。
  2. 死循環阻塞 EDT:while(flag) 直接在 EDT 中無限循環打印,導致界面無法響應任何事件(包括 Stop 按鈕點擊、重繪等)。
  3. 共享變量無同步:flag 非 volatile,多線程可見性無保障。

正確設計模式

// 1. 使用 SwingWorker 或獨立工作線程執行耗時任務
// 2. 通過標誌位控制循環,確保 volatile 可見性
private volatile boolean running = false;

btnStart.addActionListener(e -> {
    running = true;
    new Thread(() -> {
        while (running) {
            System.out.println("running...");
            try { Thread.sleep(100); } catch (InterruptedException ignored) {}
        }
    }).start();
});

btnStop.addActionListener(e -> running = false);

關鍵點總結

  • 永遠不要在 EDT 中執行耗時/阻塞操作;
  • 線程間共享變量必須用 volatile 或原子類;
  • Swing 線程安全:更新 UI 必須用 SwingUtilities.invokeLater()。

討論截圖

討論截圖

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