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

Java 多線程基石:繼承 Thread 類完整指南與常見誤區

     編輯:Java 相關知識

最直觀的線程啟動方式

定義一個類繼承 java.lang.Thread,重寫 run() 方法放入執行邏輯,建立實例後呼叫 start() 即可啟動新線程。JVM 會在新線程中自動呼叫 run()。

最小化完整範例


public class FirstThread extends Thread {
    public static void main(String[] args) {
        FirstThread ft = new FirstThread();
        ft.start(); // 啟動子線程
        
        // 主線程繼續執行
        for (int i = 0; i < 10; i++) {
            try { Thread.sleep(1000); } catch (InterruptedException e) {}
            System.out.println("main:" + i);
        }
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try { Thread.sleep(1000); } catch (InterruptedException e) {}
            System.out.println("run:" + i);
        }
    }
}

執行結果與並發證明


run:0
main:0
main:1
run:1
main:2
run:2
...

輸出交錯出現,證明 main 與 run 兩條線程真正並發執行。順序不固定,取決於作業系統排程器。

關鍵機制深度解析

1. start() vs run()

  • start():啟動新線程,JVM 分配棧幀、PC 計數器,非阻塞立即返回。
  • run():普通方法呼叫,在當前線程同步執行,不會開啟新線程。

❌ 錯誤:ft.run(); → 單線程循序執行。
✅ 正確:ft.start(); → 多線程並發。

2. 線程生命週期:新建 → 運行 → 死亡

  • 新建:new FirstThread(),物件建立但未啟動。
  • 運行:呼叫 start() 後,進入就緒/運行狀態,由 OS 排程。
  • 死亡:run() 方法正常返回或拋出未捕獲異常,線程終止,資源釋放。

3. 主線程 vs 子線程:誰決定程式結束?

JVM 只有在所有非守護線程結束後才退出。主線程 main() 結束不代表程式結束——若子線程還在跑,程式會繼續運行。

代碼組織最佳實踐:獨立線程類


// 獨立線程類:單一職責,可複用
public class ThirdThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try { Thread.sleep(1000); } catch (InterruptedException e) {}
            System.out.println("run:" + i);
        }
    }
}

// 使用端:隨時隨地啟動多個實例
public class Test {
    public static void main(String[] args) {
        new ThirdThread().start(); // 線程 1
        new ThirdThread().start(); // 線程 2,獨立運行
        
        // 主線程邏輯...
    }
}

⚠️ 致命誤區:同一線程實例不能 start() 兩次


Thread t = new ThirdThread();
t.start(); // OK
t.start(); // ❌ IllegalThreadStateException:線程已啟動過

若需重複執行同樣邏輯,請 new 多個實例,或改用 Runnable + 線程池。

進階技巧:提取公共邏輯避免重複


public class SecondThread extends Thread {
    public static void main(String[] args) {
        new SecondThread().start();
        print("main:");
    }
    @Override public void run() { print("run:"); }
    
    private static void print(String prefix) {
        for (int i = 0; i < 10; i++) {
            try { Thread.sleep(1000); } catch (InterruptedException e) {}
            System.out.println(prefix + i);
        }
    }
}

run() 呼叫的 print() 同樣在新線程中執行,結構清晰、零重複。

總結:繼承 Thread 的定位

優點缺點
語法簡單、直觀、適合入門教學佔用單繼承名額,任務與執行緒強耦合
可直接存取 this 訪問線程屬性難以複用邏輯、難以配合線程池

建議:教學/原型階段可用;正式專案請優先選擇 實作 Runnable + ExecutorService。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved