首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 多執行緒實現兩大核心方式:繼承 Thread vs 實現 Runnable 深度對比

     編輯:Java 綜合教學

Java 多執行緒啟動機制全解析:Thread、Runnable 與最佳實踐

Java 提供兩種基礎方式創建執行緒:**繼承 Thread 類**與**實現 Runnable 介面**。本文深度剖析兩者原理差異、優劣勢、源碼機制,並延伸至現代並發框架的最佳實踐。

一、方式一:繼承 Thread 類

核心代碼

public class AntThread extends Thread {
    private final String name;
    
    public AntThread(String name) { this.name = name; }
    
    @Override
    public void run() {
        while (true) {
            try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println(name + " 螞蟻正在下載......");
        }
    }
}

// 啟動
public static void main(String[] args) {
    new AntThread("1號").start();
    new AntThread("2號").start();
}

關鍵特性

  • Thread 本身實現了 Runnable,run() 為空實現。
  • 唯一啟動入口:start() (native 方法) → 分配 OS 執行緒 → 調用 run()。
  • 直接 run() **不會啟動新執行緒**,僅在主執行緒同步執行。
  • 每個 Thread 子類實例 = 一個執行緒,**無法復用任務邏輯**。

二、方式二:實現 Runnable 介面

核心代碼

public class Task implements Runnable {
    @Override
    public void run() {
        System.out.println("任務執行: " + Thread.currentThread().getName());
    }
}

// 啟動:包裝進 Thread
public static void main(String[] args) {
    Task task = new Task();
    new Thread(task, "Worker-1").start();
    new Thread(task, "Worker-2").start(); // 同一任務實例可被多執行緒共享
}

源碼揭秘:Thread 如何執行 Runnable

// Thread.java 核心片段
private Runnable target; // 目標任務

public Thread(Runnable target) {
    this.target = target;
}

@Override
public void run() {
    if (target != null) {
        target.run(); // 委派給 Runnable
    }
}

核心優勢

  1. 解耦任務與執行緒:同一 Runnable 可提交給多個執行緒、執行緒池、CompletableFuture 等。
  2. 突破單繼承限制:類可繼承其他業務基類,同時實現 Runnable。
  3. 支援 Lambda (Java 8+):new Thread(() -> System.out.println("Hi")).start();
  4. 資源共享容易:多執行緒操作同一 Runnable 實例的字段,天然共享狀態。

三、深度對比表

維度繼承 Thread實現 Runnable
繼承限制佔用單繼承名額無限制,可繼承其他類
任務復用不可復用 (1 實例 = 1 執行緒)可被多執行緒/池復用
共享狀態需額外傳遞共享物件天然共享 this 字段
Lambda 支援無 (需匿名內部類)完美支援
適用場景簡單獨立任務、教學演示所有生產級開發、並發框架基石

四、進階:第三種方式——Callable + Future (有返回值)

Callable task = () -> {
    Thread.sleep(1000);
    return 42;
};

FutureTask futureTask = new FutureTask<>(task);
new Thread(futureTask).start();

Integer result = futureTask.get(); // 阻塞獲取結果
System.out.println("結果: " + result);

五、現代最佳實踐:執行緒池與 CompletableFuture

生產環境禁用 new Thread() 直接創建執行緒,原因:

  • 頻繁創建/銷毀開銷大
  • 無限制創建導致 OOM
  • 無法統一管理、監控、調優

標準執行緒池提交任務

ExecutorService executor = Executors.newFixedThreadPool(4); // 或自定義 ThreadPoolExecutor
executor.submit(() -> System.out.println("池中執行"));
executor.shutdown();

CompletableFuture 異步編排 (Java 8+)

CompletableFuture.supplyAsync(() -> "Hello")
    .thenApply(s -> s + " World")
    .thenAccept(System.out::println)
    .join();

六、總結與建議

  1. 理解本質:Thread 是執行緒控制對象,Runnable 是任務單元,**任務與執行緒分離**是核心設計模式。
  2. 首選 Runnable/Lambda:靈活、可復用、適配並發框架。
  3. 生產用執行緒池:ThreadPoolExecutor 精細控制核心/最大/隊列/拒絕策略。
  4. 避免繼承 Thread:除非極簡單 Demo 或需覆寫 Thread 行為 (如自定義 ThreadLocal 繼承鏈)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved