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

Java 多線程核心技術全景:從基礎 API 到線程池與鎖優化

     編輯:Java 綜合教學

線程基礎概念

  • 單線程程式:單一執行路徑。
  • 多線程程式:多條執行路徑。進程為執行中應用程式,線程為進程執行單元/路徑。
  • JVM 啟動即為多線程:主線程 + GC 線程至少兩條。

三大實作方案

  1. 繼承 Thread 類別:覆寫 run(),呼叫 start() 啟動。
  2. 實作 Runnable 介面:實作 run(),傳入 Thread 建構子。優勢:避免單繼承限制、適合資源共享場景(同一 Runnable 實例多線程共用)。
  3. 實作 Callable 介面 + 線程池(JDK 5+):call() 可回傳值、拋出異常,配合 Future 獲取結果。

比較圖示:

線程調度與優先級

  • Java 採搶佔式調度(非分時調度)。
  • 優先級 1-10,預設 5。getPriority()/setPriority()。高優先級獲得較多 CPU 時間片,但非絕對保證。

線程常用控制方法

線程生命週期

六狀態:NEW → RUNNABLE → BLOCKED/WAITING/TIMED_WAITING → TERMINATED。狀態轉換圖:

線程安全與同步機制

問題根因(三要素)

  1. 多線程環境
  2. 共享資料
  3. 多條語句操作共享資料(非原子)

經典售票案例:sleep(100) 放大並發衝突,導致重賣、負票。

同步解決方案

  • 同步程式碼塊:synchronized(obj) { ... },鎖為任意物件。
  • 同步方法:synchronized void method(),鎖為 this。
  • 靜態同步方法:鎖為當前類別 Class 物件。

線程安全集合類別:StringBuffer、Vector、Hashtable。非安全集合可用 Collections.synchronizedXxx() 包裝。

JDK 5+ 顯式鎖

private Lock lock = new ReentrantLock();
public void run() {
    while (true) {
        try {
            lock.lock();
            if (tickets > 0) { /* 賣票邏輯 */ }
        } finally {
            lock.unlock(); // 必須在 finally 釋放
        }
    }
}

ReentrantLock 支援公平/非公平模式、條件變數(Condition)、可中斷鎖獲取等進階功能。

死鎖與避免

兩線程互相持有對方所需鎖(巢狀 synchronized 且鎖順序相反)。避免策略:固定全域鎖獲取順序、使用 tryLock(timeout)、縮小鎖範圍。

生產者-消費者(等待/通知機制)

  • wait():線程釋放鎖進入等待集合,被喚醒後重新競爭鎖繼續執行。
  • notify():喚醒單一等待線程(轉 RUNNABLE)。
  • notifyAll():喚醒所有等待線程(多生產多消費必須)。

定義於 Object,因鎖對象任意,需透過鎖對象呼叫。最佳實踐:將同步、等待、通知封裝於資源類別內部。

進階特性

線程組

ThreadGroup 批量管理線程。預設屬 main 組。可建立自訂組並設為守護組(tg.setDaemon(true))。

線程池

降低頻繁建立/銷毀線程開銷(涉及 OS 互動)。Executors 工廠:

  • newCachedThreadPool():可緩存線程,適合大量短生命任務。
  • newFixedThreadPool(n):固定大小,可重用。
  • newSingleThreadExecutor():單線程序列化執行。

ExecutorService 提交 Runnable/Callable 回傳 Future。shutdown() 有序關閉。

匿名內部類快速建立線程

new Thread() { public void run() { ... } }.start();
new Thread(new Runnable() { public void run() { ... } }).start();

定時器應用

Timer 排程 TimerTask(run() 定義任務),支援單次/週期執行。生產環境推薦 Quartz 框架(功能更豐富、支援叢集)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法說明
sleep(long ms)靜態方法,讓當前線程休眠指定毫秒,不釋放鎖。
join()等待目標線程終止,當前線程阻塞。
yield()靜態方法,提示調度器當前線程願意讓出 CPU,非強制。
setDaemon(true)標記為守護線程(需在 start() 前呼叫)。僅剩守護線程時 JVM 退出。
interrupt()中斷線程:阻塞狀態拋 InterruptedException;運行狀態設中斷旗標,需自行檢查 isInterrupted()。
stop()已棄用,強制終止導致資料不一致。