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

Java 多執行緒核心技術:從 Thread 基礎到同步機制

     編輯:Java 程式設計入門

為什麼需要多執行緒?

單執行緒程式:四個無關任務 (列印、檔案操作、資料庫、繪圖) 循序執行,每個任務含 I/O 等待,總耗時 = 總和。資源利用率極低。

多執行緒:任務並行,等待期可切換執行其他任務,大幅提升吞吐量與回應性。

兩種並行實現方式

方式進程執行緒
建立開銷大 (獨立記憶體空間、PCB)小 (共享進程記憶體、輕量級)
通訊難度高 (IPC: pipe, socket, shared memory)低 (共享堆記憶體、同步工具)
穩定性高 (隔離性好)較低 (一執行緒崩潰影響全進程)
適用場景獨立服務、安全沙箱高併發、資料共享、即時互動

Java 內建執行緒支援,跨平台一致,是首選方案。

Java 執行緒兩種建立方式

方式一:繼承 Thread 類別

class TimePrinter extends Thread {
    private int pauseTime;
    private String name;
    
    public TimePrinter(int pauseTime, String name) {
        this.pauseTime = pauseTime;
        this.name = name;
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(name + ": " + new Date());
            try { Thread.sleep(pauseTime); } catch (InterruptedException e) {}
        }
    }
}

// 使用
new TimePrinter(1000, "Thread-A").start();
new TimePrinter(2000, "Thread-B").start();

關鍵: 必須呼叫 start() (啟動新執行緒並呼叫 run()),不可直接呼叫 run() (會在主執行緒同步執行)。

方式二:實作 Runnable 介面 (推薦)

class Task implements Runnable {
    public void run() { /* 任務邏輯 */ }
}

new Thread(new Task()).start();
// 或使用執行緒池
ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(new Task());

優勢: 解耦任務邏輯與執行緒控制、支援執行緒池、避免單繼承限制。

執行緒生命週期

NEW → RUNNABLE → RUNNING → BLOCKED/WAITING/TIMED_WAITING → TERMINATED
     start()      排程器分派      sleep/wait/join/IO          run() 結束

同步機制:解決共享資料競態

1. synchronized 關鍵字

// 同步方法
public synchronized void deposit(int amount) {
    balance += amount;
}

// 同步區塊 (更精細鎖粒度)
public void withdraw(int amount) {
    synchronized (this) {
        balance -= amount;
    }
}

// 靜態方法鎖定 Class 物件
public static synchronized void staticMethod() { ... }

2. wait() / notify() / notifyAll() — Object 等待通知機制

// 生產者
synchronized (buffer) {
    while (buffer.isFull()) buffer.wait(); // 釋放鎖並等待
    buffer.add(item);
    buffer.notifyAll(); // 喚醒消費者
}

// 消費者
synchronized (buffer) {
    while (buffer.isEmpty()) buffer.wait();
    Item item = buffer.remove();
    buffer.notifyAll(); // 喚醒生產者
}

核心規則:

  • 只能在 synchronized 區塊/方法內 呼叫
  • wait():釋放鎖,進入等待集合
  • notify():喚醒一個等待執行緒
  • notifyAll():喚醒所有等待執行緒 (推薦,避免訊號遺失)
  • 喚醒後需重新獲得鎖才能繼續執行

3. 經典範例:ThreadA 等待 ThreadB 完成

class ThreadB extends Thread {
    int total;
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 100; i++) total += i;
            notify(); // 通知等待者
        }
    }
}

public class ThreadA {
    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();
        synchronized (b) {           // 鎖定 b 物件
            try { b.wait(); }        // 釋放 b 的鎖並等待
            catch (InterruptedException e) {}
        }
        System.out.println("Total: " + b.total);
    }
}

流程: main 執行緒鎖定 b → 呼叫 wait() 釋放鎖並睡眠 → ThreadB 運行完畢呼叫 notify() → main 重新獲得鎖繼續執行。

現代替代方案 (JDK 5+)

  • Lock / Condition:ReentrantLock、Condition.await/signal,功能更強
  • 並發集合:ConcurrentHashMap、BlockingQueue、CopyOnWriteArrayList
  • 原子變數:AtomicInteger、LongAdder
  • 執行緒池:ExecutorService、CompletableFuture (非同步組合)
  • Fork/Join:分治任務並行

總結

掌握 Thread/Runnable、synchronized、wait/notify 是 Java 並發基石。實務開發優先使用高階並發工具 (JUC 套件),降低同步錯誤風險,提升可維護性。

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