public class MyThread extends Thread {
private final String name;
public MyThread(String name) { this.name = name; }
@Override
public void run() {
System.out.println(name + " 運行中...");
// 業務邏輯
}
}
// 啟動
new MyThread("Thread-A").start();
public class MyRunnable implements Runnable {
private final String name;
public MyRunnable(String name) { this.name = name; }
@Override
public void run() {
System.out.println(name + " 運行中...");
}
}
// 啟動:包裝成 Thread
new Thread(new MyRunnable("Runnable-B")).start();
// 匿名內部類
new Thread(() -> System.out.println("Lambda 線程")).start();
| 維度 | 繼承 Thread | 實現 Runnable |
|---|---|---|
| 繼承限制 | 佔用單繼承名額 | 無限制,可繼承其他類 |
| 資源共享 | 每實例獨有字段,難共享 | 同一實例可被多線程共享 |
| 職責分離 | 線程控制與任務邏輯耦合 | 任務邏輯獨立,配合線程池最佳 |
| 線程池適配 | 不直接支持 | ExecutorService 原生支持 |
| 推薦場景 | 簡單測試、教學演示 | 生產代碼、並發任務 |
// Thread 子類:每個實例獨有 count,賣票系統會超賣
class TicketThread extends Thread {
private int tickets = 100;
public void run() { while(tickets>0) sell(); }
}
new TicketThread().start(); new TicketThread().start(); // 各賣 100 張!
// Runnable:共享同一實例,正確賣 100 張
class TicketRunnable implements Runnable {
private int tickets = 100;
public void run() { while(tickets>0) sell(); }
}
TicketRunnable task = new TicketRunnable();
new Thread(task).start(); new Thread(task).start(); new Thread(task).start();
start():異步啟動,JVM 分配線程資源,調度執行 run()run():普通方法調用,同步在當前線程執行,不是多線程Thread 實例只能 start() 一次,重複調用拋 IllegalThreadStateExceptionnew Thread(runnable, "名字") 或 thread.setName()Thread.currentThread()| 誤區 | 錯誤代碼 | 正確代碼 | 後果 |
|---|---|---|---|
| 調用 run() 代替 start() | t.run(); | t.start(); | 主線程同步執行,無並發效果 |
| 重複 start 同一實例 | t.start(); t.start(); | new Thread(r).start(); | IllegalThreadStateException |
| 匿名類未啟動 | new Thread(() -> {}); | new Thread(() -> {}).start(); | 線程對象創建但從未運行 |
| 主線程過早結束 | 無 join/同步 | t.join(); / CountDownLatch | 守護線程隨 JVM 退出 |
// 設置有意義名稱,便於日誌追蹤、Arthas 診斷
Thread producer = new Thread(new Producer(), "Order-Producer-1");
Thread consumer = new Thread(new Consumer(), "Order-Consumer-1");
// 線程組批量管理(較少用)
ThreadGroup group = new ThreadGroup("Order-Processing");
new Thread(group, task, "Worker-1").start();
// 避免頻繁創建銷毀開銷,防止 OOM
ExecutorService pool = Executors.newFixedThreadPool(10); // 固定大小
// 或自定義參數
ThreadPoolExecutor pool = new ThreadPoolExecutor(
10, 50, 60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100),
new ThreadFactoryBuilder().setNameFormat("Biz-Worker-%d").build(),
new ThreadPoolExecutor.AbortPolicy()
);
pool.submit(() -> { /* 任務 */ });
pool.shutdown(); // 優雅關閉
public class ThreadDemo {
public static void main(String[] args) {
System.out.println("主線程: " + Thread.currentThread().getName());
for (int i = 1; i <= 10; i++) {
final int num = i;
new Thread(() -> {
System.out.println("線程 " + num + " (" + Thread.currentThread().getName() + ") 啟動");
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
System.out.println("線程 " + num + " 結束");
}, "Worker-" + i).start();
}
// 主線程等待所有子線程(示例簡化,實際用 CountDownLatch)
try { Thread.sleep(2000); } catch (InterruptedException ignored) {}
System.out.println("主線程結束");
}
}
輸出特徵:啟動順序固定,但運行順序隨機,由 OS 調度器決定,驗證並發非順序執行本質。
線程創建看似簡單,實則蘊含異步啟動機制、資源共享模型、線程池工程化等核心知識。牢記:任務邏輯實現 Runnable,執行控制交給 Thread/Executor,這是並發編程工程化的基石。