多線程是 Java 並發編程的基石。本文通過對比 Thread 繼承與 Runnable 實現、深度剖析 start() 底層機制,建立正確的多線程啟動認知。
public class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name + " 執行: " + i);
// 適當休眠觀察交替執行
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
}
}
public static void main(String[] args) {
new MyThread("線程-A").start();
new MyThread("線程-B").start();
new MyThread("線程-C").start();
}
}
public class MyRunnable implements Runnable {
private String name;
public MyRunnable(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name + " 執行: " + i);
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
}
}
public static void main(String[] args) {
// 單一任務實例可被多線程共享
MyRunnable task = new MyRunnable("任務");
new Thread(task, "線程-1").start();
new Thread(task, "線程-2").start();
new Thread(task, "線程-3").start();
}
}
| 維度 | 繼承 Thread | 實現 Runnable |
|---|---|---|
| 繼承限制 | 單繼承,無法繼承其他業務類 | 無繼承限制,可繼承其他類 |
| 任務共享 | 每個線程獨立任務實例 | 同一 Runnable 可被多線程共享 |
| 邏輯分離 | 線程控制與任務邏輯耦合 | 線程控制與任務邏輯解耦 |
| 適用場景 | 簡單獨立任務 | 企業級開發標準、線程池提交 |
public static void main(String[] args) {
MyThread mt1 = new MyThread("A");
MyThread mt2 = new MyThread("B");
MyThread mt3 = new MyThread("C");
mt1.run(); // 直接呼叫 run() - 順序執行!
mt2.run();
mt3.run();
}
輸出結果:
A 執行: 0 ... A 執行: 9 B 執行: 0 ... B 執行: 9 C 執行: 0 ... C 執行: 9 (三個線程依序順序執行,無並發)
public static void main(String[] args) {
new MyThread("A").start();
new MyThread("B").start();
new MyThread("C").start();
}
輸出結果:
A 執行: 0 B 執行: 0 C 執行: 0 A 執行: 1 B 執行: 1 ... (三個線程交替並發執行,順序不確定)
public synchronized void start() {
// 1. 狀態檢查:NEW 狀態才能啟動
if (threadStatus != 0)
throw new IllegalThreadStateException();
// 2. 加入線程組
group.add(this);
boolean started = false;
try {
// 3. 核心:呼叫 native 方法啟動系統線程
start0();
started = true;
} finally {
if (!started) {
group.threadStartFailed(this); // 啟動失敗清理
}
}
}
// Native 方法:由 JVM 根據 OS 實現 (C++ 代碼)
private native void start0();
pthread_create() 建立 POSIX 線程CreateThread() 或 _beginthreadex()-Xss 調整)run() 方法執行用戶代碼public enum State {
NEW, // 新建:new Thread(),未 start()
RUNNABLE, // 可執行:start() 後,含 Running/Ready
BLOCKED, // 阻塞:等待監視器鎖 (synchronized)
WAITING, // 等待:Object.wait()、Thread.join()、LockSupport.park()
TIMED_WAITING, // 限時等待:sleep、wait(timeout)、join(timeout)
TERMINATED // 終止:run() 正常返回或拋出未捕獲異常
}


ExecutorService + ThreadPoolExecutor,避免頻繁建立/銷毀線程開銷Future 獲取結果,CompletableFuture 異步編排Thread.startVirtualThread() 或 Executors.newVirtualThreadPerTaskExecutor(),輕量級高併發新選擇new Thread(task, "order-process-%d") 便於日誌追蹤與 Arthas 排查interrupt() 標誌位 + 迴圈檢查 Thread.interrupted(),避免 stop() (已棄用、不安全)。