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

線程池與工作隊列:高併發服務器的核心架構

     編輯:Java 程式設計入門

為何需要線程池?

Web 服務器、資料庫服務器等典型服務端應用面臨海量短小任務請求。若採用「每請求一線程」模型,頻繁創建/銷毀線程的開銷將遠超業務處理本身,且大量活躍線程會耗盡記憶體導致「切換過度」。線程池通過重用固定數量線程解決這兩大問題:

  • 線程創建開銷分攤到多個任務。
  • 請求到達時線程已就緒,消除創建延遲,響應更快。
  • 通過限制線程數上限,防止資源耗盡,超載請求排隊等待。

替代方案及其局限

  • 每任務一線程: 適合少量長任務,高頻短任務下性能崩潰。
  • 單後台線程 + 任務隊列: AWT/Swing 採用此模型(EDT)。缺點是長任務會阻塞唯一線程,導致 UI 無響應,故 Swing 需額外工作線程(如 SwingWorker)。

線程池結合了固定工作線程組與共享工作隊列,兼具低開銷、資源管控與調度可預測性,是高併發服務器的首選。

工作隊列實現核心模式

術語「線程池」易誤導人以為是「線程對象池」。實際高效實現是:固定線程組 + 阻塞隊列 + wait/notify 協作。調用者將 Runnable 任務入隊並 notify();工作線程從隊列 take() 任務執行,空隊列時 wait() 掛起。

簡易工作隊列示例

public class WorkQueue {
    private final int nThreads;
    private final PoolWorker[] threads;
    private final LinkedList<Runnable> queue = new LinkedList<>();

    public WorkQueue(int nThreads) {
        this.nThreads = nThreads;
        threads = new PoolWorker[nThreads];
        for (int i = 0; i < nThreads; i++) {
            threads[i] = new PoolWorker();
            threads[i].start();
        }
    }

    public void execute(Runnable r) {
        synchronized (queue) {
            queue.addLast(r);
            queue.notify();
        }
    }

    private class PoolWorker extends Thread {
        public void run() {
            Runnable r;
            while (true) {
                synchronized (queue) {
                    while (queue.isEmpty()) {
                        try { queue.wait(); } catch (InterruptedException ignored) {}
                    }
                    r = queue.removeFirst();
                }
                try { r.run(); } 
                catch (RuntimeException e) { /* 記錄日誌,防止線程泄漏 */ }
            }
        }
    }
}

關鍵點:

  • 同步鎖保護隊列操作。
  • wait() 釋放鎖讓生產者入隊;notify() 喚醒消費者。
  • 捕獲 RuntimeException 防止工作線程意外終止導致線程池縮水。
  • 此模式為標準 ExecutorService / ThreadPoolExecutor 的基礎原型。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved