每次點擊按鈕執行 new Thread(runnable).start() 都會創建一個全新的線程並發運行,而非在原線程中排隊。先啟動的線程若任務輕量(如打印日誌),極大概率已在新線程啟動前執行完畢。
Thread.start() 為 native 方法,底層調用 pthread_create 創建內核線程。同一 Thread 實例調用兩次 start() 會拋出 IllegalThreadStateException,證明線程不可復用。
// 錯誤示範:嘗試復用線程對象
Thread t = new Thread(runnable);
t.start();
// ...
t.start(); // 💥 IllegalThreadStateException
Runnable task = () -> {
String name = Thread.currentThread().getName();
System.out.println(name + " 開始");
try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
System.out.println(name + " 結束");
};
// 連續點擊 3 次
for (int i = 0; i < 3; i++) {
new Thread(task).start();
}
// 輸出示例(交替出現,證明並發):
// Thread-0 開始
// Thread-1 開始
// Thread-2 開始
// Thread-0 結束
// Thread-1 結束
// Thread-2 結束
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 高頻短任務 | 線程池 Executors.newFixedThreadPool() | 避免頻繁創建銷毀開銷、控制併發上限 |
| 需按序執行 | 單線程池 Executors.newSingleThreadExecutor() | 天然保證任務順序、避免競態 |
| 需取消/進度 | Kotlin Coroutines / RxJava / CompletableFuture | 結構化併發、取消傳播、背壓處理 |
| Android UI 更新 | runOnUiThread / Handler(Looper.getMainLooper()) / LiveData | 主線程安全更新、生命周期感知 |
Thread.currentThread() 可區分線程身份」—— 結合 getId()/getName() 精確追蹤理解「new Thread = 新內核線程」本質,拒絕盲目創建,善用線程池與結構化併發框架,構建高性能穩定的併發應用。