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

Java 多線程入門實戰:Thread 繼承 vs Runnable 實現、線程控制與優先級

     編輯:Java 相關知識

兩種創建線程的方式對比

方式一:繼承 Thread 類

class ThreadUseExtends extends Thread {
    @Override public void run() {
        System.out.println("我是 Thread 子類線程實例!");
        System.out.println("我將掛起 10 秒!");
        try { sleep(10000); } catch (InterruptedException e) { return; }
        // run() 正常結束,線程自動終止
    }
}
// 使用
ThreadUseExtends thread1 = new ThreadUseExtends();
thread1.start(); // 進入就緒狀態,獲取 CPU 後自動調用 run()

方式二:實現 Runnable 接口(推薦)

class ThreadUseRunnable implements Runnable {
    @Override public void run() {
        System.out.println("我是實現 Runnable 接口的線程實例!");
        System.out.println("我將掛起 1 秒!");
        try { Thread.sleep(1000); } catch (InterruptedException e) { return; }
    }
}
// 使用
Thread thread2 = new Thread(new ThreadUseRunnable(), "SecondThread");
thread2.start();

核心差異: Runnable 將任務與線程控制解耦,支持線程池、Lambda 表達式,避免單繼承限制,是現代開發首選。

主線程控制子線程完整示例

public class MultiThread {
    public static void main(String[] args) {
        System.out.println("我是主線程!");

        ThreadUseExtends thread1 = new ThreadUseExtends();
        Thread thread2 = new Thread(new ThreadUseRunnable(), "SecondThread");

        thread1.start();
        System.out.println("主線程將掛起 7 秒!");
        sleepMain(7000);

        // 檢查 thread1 存活,超時則強制停止(注意:stop() 已棄用,不推薦生產使用)
        if (thread1.isAlive()) {
            thread1.stop(); // 僅教學演示
            System.out.println("thread1 休眠過長,主線程殺掉了 thread1!");
        } else {
            System.out.println("thread1 已正常結束!");
        }

        thread2.start();
        System.out.println("主線程又將掛起 7 秒!");
        sleepMain(7000);

        if (thread2.isAlive()) {
            thread2.stop();
            System.out.println("thread2 休眠過長,主線程殺掉了 thread2!");
        } else {
            System.out.println("thread2 已正常結束!");
        }
        System.out.println("程序結束,按任意鍵退出...");
        waitForEnter();
    }

    static void sleepMain(long ms) {
        try { Thread.sleep(ms); } catch (InterruptedException e) { return; }
    }
    static void waitForEnter() {
        try { System.in.read(); } catch (IOException e) { e.printStackTrace(); }
    }
}

關鍵知識點補充

1. 線程優先級

  • MIN_PRIORITY=1, NORM_PRIORITY=5 (默認), MAX_PRIORITY=10
  • thread.setPriority(Thread.MAX_PRIORITY)
  • 優先級高的線程獲得更多 CPU 時間片,但不保證執行順序,受 OS 調度器支配。

2. 線程狀態與生命周期

start() → 就緒 → (獲取 CPU) → 運行 → sleep()/wait()/join() → 阻塞 → 就緒 → ... → run() 結束 → 終止。

3. 棄用方法警示

  • Thread.stop()、suspend()、resume() 已棄用,會導致鎖釋放不一致、數據損壞。
  • 正確停止線程:共享標誌位 + interrupt() 模式。

4. 守護線程

thread.setDaemon(true):JVM 僅剩守護線程時自動退出。適合後台監控、定時清理任務。

最佳實踐建議

  1. 優先使用 Runnable + Thread 或線程池 ExecutorService。
  2. 避免直接操作 Thread 實例管理生命周期,改用 Future, CountDownLatch, CompletableFuture 等高層協作工具。
  3. 線程命名:new Thread(runnable, "意味名稱"),極大便利日誌追蹤與調試。
  4. 異常處理:run() 不拋受檢異常,需內部 try-catch 或使用 Thread.UncaughtExceptionHandler。

多線程入門看似簡單,實則暗藏「可見性、原子性、有序性」三大核心挑戰。建議從《Java 並發編程實戰》系統學習,構建正確的並發思維模型。

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