Java 內建多線程支援,`main()` 方法本身即運行於主線程。創建新線程有兩條標準路徑:繼承 `Thread` 或實現 `Runnable` (Java 8+ 推薦 Lambda/方法引用)。
class TimePrinter extends Thread {
private final int intervalMs;
private final String name;
public TimePrinter(int intervalMs, String name) {
this.intervalMs = intervalMs;
this.name = name;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.printf("%s: %s%n", name, new java.util.Date());
Thread.sleep(intervalMs);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 保持中斷狀態
break;
}
}
}
}
// 使用
TimePrinter fast = new TimePrinter(1000, "Fast");
TimePrinter slow = new TimePrinter(3000, "Slow");
fast.start(); // 必須呼叫 start(),而非 run()
slow.start();
class TimePrinter implements Runnable {
private final int intervalMs;
private final String name;
public TimePrinter(int intervalMs, String name) {
this.intervalMs = intervalMs;
this.name = name;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.printf("%s: %s%n", name, new java.util.Date());
Thread.sleep(intervalMs);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
}
// 使用:將 Runnable 包裝進 Thread
Thread t1 = new Thread(new TimePrinter(1000, "Fast"));
Thread t2 = new Thread(new TimePrinter(3000, "Slow"));
t1.start();
t2.start();
// Java 8+ Lambda 更簡潔
Thread t3 = new Thread(() -> {
while (!Thread.interrupted()) {
System.out.println("Lambda: " + new java.util.Date());
try { Thread.sleep(2000); } catch (InterruptedException e) { break; }
}
});
t3.start();
| 維度 | extends Thread | implements Runnable |
|---|---|---|
| 類別層次 | 佔用單繼承名額 | 不影響類別繼承體系 |
| 職責分離 | 線程控制與任務邏輯混合 | 任務邏輯獨立,可重用、可提交給執行緒池 |
| 資源共享 | 需額外傳遞共享物件 | 天然共享同一 Runnable 實例的欄位 |
| 現代最佳實踐 | 極少使用 | 標準寫法,配合 ExecutorService |
class Account {
private String owner;
private double balance;
public Account(String owner, double balance) {
this.owner = owner;
this.balance = balance;
}
// 非線程安全
public void deposit(double amt) { balance += amt; }
public void withdraw(double amt) { balance -= amt; }
public double getBalance() { return balance; }
}
public synchronized void deposit(double amt) { balance += amt; }
public synchronized void withdraw(double amt) { balance -= amt; }
public void deposit(double amt) {
synchronized (this) { balance += amt; }
}
private final Object balanceLock = new Object();
public void deposit(double amt) {
synchronized (balanceLock) { balance += amt; }
}
《Java 多線程編程精要 (二)》將深入講解:wait/notify 機制、生產者消費者模式、ThreadLocal、CompletableFuture 非阻塞組合、虛擬線程。