| 工具 | 適用場景 | 關鍵特點 |
|---|---|---|
| java.util.Timer | 簡單重複任務、後台非 GUI | 單線程調度、毫秒精度、任務定義在 TimerTask.run() |
| javax.swing.Timer | GUI 定時更新、Swing 組件操作 | 事件分發線程(EDT)執行、ActionListener 介面、線程安全 |
| Thread 繼承 | 長時間運行、需自定義線程行為 | 覆寫 run()、start() 啟動、單繼承限制 |
| Runnable 實現 | 解耦任務邏輯、靈活配合線程池 | 實現 run()、傳給 Thread 建構子、無繼承限制 |
TimerTask task = new TimerTask() {
public void run() { System.out.println("Hi"); }
};
Timer timer = new Timer();
timer.schedule(task, 0, 500); // 立即開始,間隔 500ms
System.in.read(new byte[10]); // 等待 Enter
timer.cancel();
JFrame frame = new JFrame();
JLabel label = new JLabel("0", JLabel.CENTER);
label.setFont(new Font("Serif", Font.PLAIN, 36));
frame.add(label);
ActionListener listener = new ActionListener() {
int count = 0;
public void actionPerformed(ActionEvent e) {
label.setText(String.valueOf(++count)); // 安全更新 GUI
}
};
new Timer(500, listener).start();
frame.setSize(300, 100);
frame.setVisible(true);
核心差異:Swing Timer 在 EDT 執行,可直接操作組件;util.Timer 在工作線程,操作 GUI 需 SwingUtilities.invokeLater()。
RunnableThread 亦可Runnable + 線程池 (ExecutorService)Thread downloader = new Thread(() -> {
try (BufferedReader r = new BufferedReader(
new InputStreamReader(new URL(url).openStream()))) {
int cnt = 0; while (r.read() != -1) cnt++;
System.out.println("Size: " + cnt);
} catch (Exception e) { e.printStackTrace(); }
});
Thread printer = new Thread(() -> {
while (true) {
System.out.println(msg);
Thread.sleep(500);
}
});
downloader.start(); printer.start();