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

Java 線程啟動核心:start() 與 run() 方法本質差異解析

     編輯:Java 相關知識

兩種建立線程的方式

方式一:實作 Runnable 介面

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("透過 Runnable 建立線程");
    }
}).start();

方式二:繼承 Thread 類別並覆寫 run()

new Thread() {
    @Override
    public void run() {
        System.out.println("繼承 Thread 建立線程");
    }
}.start();

源碼層面深度解析

Thread.start() 方法

public synchronized void start() {
    if (threadStatus != 0)
        throw new IllegalThreadStateException();
    group.add(this);
    boolean started = false;
    try {
        start0();           // ★ 關鍵:呼叫 native 方法啟動線程
        started = true;
    } finally {
        if (!started) {
            group.threadStartFailed(this);
        }
    }
}

start0() 是 native 方法,由 JVM 底層實作,真正建立作業系統層級線程並安排執行。

Thread.run() 方法

public void run() {
    if (target != null) {   // target 為建構子傳入的 Runnable 物件
        target.run();
    }
}

核心差異總結

方法呼叫者執行線程用途
start()主線程 (或任意線程)新建立的線程啟動新線程,由 JVM 排程執行 run()
run()任意線程呼叫者所在線程單純方法呼叫,不建立新線程

常見錯誤與誤區

❌ 直接呼叫 run()

Thread t = new Thread(() -> System.out.println("執行中"));
t.run();  // 錯誤!在主線程中同步執行,未建立新線程

✅ 正確呼叫 start()

Thread t = new Thread(() -> System.out.println("執行中"));
t.start();  // 正確!建立新線程並非同步執行

兩種建立線程方式的本質關係

  • 繼承 Thread 覆寫 run():start() → JVM 呼叫子類別的 run()
  • 實作 Runnable 傳入 Thread:start() → Thread 預設 run() → 呼叫 target.run() (即 Runnable 實作)
  • 結論:兩種方式最終效果完全相同,差別僅在程式碼組織形式

最佳實務建議

  1. 優先使用 Runnable/Lambda:避免單繼承限制,支援線程池複用,關注點分離更清晰
  2. 絕不直接呼叫 run():除非明確需要在當前線程同步執行該邏輯
  3. 線程命名:new Thread(runnable, "訂單處理線程") 便於除錯與監控
  4. 使用線程池:生產環境避免頻繁建立/銷毀線程,使用 ExecutorService
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved