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

Java 併發編程實戰(一):Runnable + Thread 啟動線程的標準姿勢

     編輯:Java 相關知識

併發基礎:進程 vs 線程 vs 並行

  • 進程:資源分配單位,擁有獨立內存空間(代碼、數據、堆);
  • 線程:CPU 調度單位,隸屬於進程,共享進程內存(堆、方法區),擁有獨立棧、程序計數器;
  • 併發:單核 CPU 分時片輪換多線程,微觀串行、宏觀並行;
  • 並行:多核 CPU 同一物理時刻真正同時執行多線程。

創建線程的兩種標準方式

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

public class Calculator implements Runnable {
    private final int number;

    public Calculator(int number) { this.number = number; }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.printf("%s: %d * %d = %d%n",
                    Thread.currentThread().getName(), number, i, i * number);
        }
    }
}

// 啟動
for (int i = 0; i < 10; i++) {
    new Thread(new Calculator(i), "Thread-" + i).start();
}

優勢:職責分離(任務邏輯 與 線程控制解耦)、支持匿名內部類/Lambda、便於提交給線程池(ExecutorService.execute(runnable))。

方式二:繼承 Thread 類(不推薦常規業務)

public class MyThread extends Thread {
    @Override public void run() { /* 任務邏輯 */ }
}
// 啟動:new MyThread().start();

劣勢:繼承佔用了唯一的 extends 名額、任務與線程控制耦合、無法直接投入線程池。

關鍵細節:start() vs run()

⚡ 核心鐵律:必須調用 start() 才會創建新線程;直接調用 run() 只是在當前線程同步執行普通方法,不會開啟新線程。

線程生命周期六大狀態

NEW → RUNNABLE → (BLOCKED / WAITING / TIMED_WAITING) → TERMINATED
  • NEW:new Thread() 但未 start();
  • RUNNABLE:就緒/運行中(操作系統調度決定);
  • BLOCKED:等待監視器鎖(synchronized);
  • WAITING:無限期等待(Object.wait()、Thread.join()、LockSupport.park());
  • TIMED_WAITING:限時等待(Thread.sleep()、wait(timeout)、join(timeout));
  • TERMINATED:run() 正常返回或拋出未捕獲異常結束。

完整可運行 Demo

public class ConcurrencyDemo1 {
    public static void main(String[] args) {
        // Lambda 寫法更簡潔
        for (int i = 0; i < 5; i++) {
            final int num = i;
            new Thread(() -> {
                for (int j = 0; j < 5; j++) {
                    System.out.printf("[%s] %d * %d = %d%n",
                            Thread.currentThread().getName(), num, j, num * j);
                }
            }, "Worker-" + i).start();
        }
        System.out.println("主線程結束,但子線程仍在運行...");
    }
}

總結

  1. 業務邏輯實現 Runnable(或 Callable),不要繼承 Thread;
  2. 啟動線程必須調用 start();
  3. 生產環境禁用裸 Thread,統一提交給 ThreadPoolExecutor 或 Spring @Async 管理;
  4. 理解六大狀態轉換,是排查死鎖、活鎖、饑餓的基礎。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved