初學者編寫的雙按鈕控制台打印程序,點擊 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; }
});
}
}
B1 的 run() 中註冊監聽器,線程啟動後立即結束,監聽器實際運行在 事件分發線程 (EDT) 中,而非新線程。while(flag) 直接在 EDT 中無限循環打印,導致界面無法響應任何事件(包括 Stop 按鈕點擊、重繪等)。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);
volatile 或原子類;SwingUtilities.invokeLater()。