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

Java 線程池原理深度解析與自訂實作完整指南

     編輯:Java 相關知識

線程池核心概念

線程池是一種多線程處理模式:任務加入隊列,由預先創建的工作線程自動取出執行。核心優勢在於降低線程創建/銷毀開銷,特別適合任務耗時短、數量大的高併發場景(如 Web 伺服器)。

四大核心組件

  1. ThreadPoolManager:創建、管理、銷毀線程池,添加任務。
  2. WorkThread:池中工作線程,空閒時等待,循環執行任務。
  3. Task:任務介面,規定執行入口、收尾、狀態。
  4. TaskQueue:緩衝未處理任務的隊列。

效能模型分析

單次任務處理時間 = T1(創建線程) + T2(執行任務) + T3(銷毀線程)。
若 T1+T3 遠大於 T2,引入線程池可將 T1、T3 移至啟動/空閒時期,顯著提升吞吐量。
例:每日 50,000 請求,無池化需創建 50,000 線程;池化僅需固定數量(如 100),大幅降低記憶體壓力與 GC 負擔。

自訂線程池完整實作

import java.util.*;
import org.apache.log4j.Logger;

public final class ThreadPool {
    private static final Logger logger = Logger.getLogger(ThreadPool.class);
    private static final Logger taskLogger = Logger.getLogger("TaskLogger");
    private static final boolean DEBUG = taskLogger.isDebugEnabled();

    private static ThreadPool instance;
    public static final int SYSTEM_BUSY_TASK_COUNT = 150;
    public static int workerNum = 5;
    private static int taskCounter = 0;
    public static boolean systemIsBusy = false;

    private final List taskQueue = Collections.synchronizedList(new LinkedList<>());
    public PoolWorker[] workers;

    private ThreadPool() { this(workerNum); }
    private ThreadPool(int n) {
        workerNum = n;
        workers = new PoolWorker[n];
        for (int i = 0; i < n; i++) workers[i] = new PoolWorker(i);
    }

    public static synchronized ThreadPool getInstance() {
        if (instance == null) instance = new ThreadPool();
        return instance;
    }

    public void addTask(Task newTask) {
        synchronized (taskQueue) {
            newTask.setTaskId(++taskCounter);
            newTask.setSubmitTime(new Date());
            taskQueue.add(newTask);
            taskQueue.notifyAll();
        }
        logger.info("Submit Task<" + newTask.getTaskId() + ">: " + newTask.info());
    }

    public void batchAddTask(Task[] tasks) {
        if (tasks == null || tasks.length == 0) return;
        synchronized (taskQueue) {
            for (Task t : tasks) if (t != null) {
                t.setTaskId(++taskCounter);
                t.setSubmitTime(new Date());
                taskQueue.add(t);
            }
            taskQueue.notifyAll();
        }
        for (Task t : tasks) if (t != null) logger.info("Submit Task<" + t.getTaskId() + ">: " + t.info());
    }

    public String getInfo() {
        StringBuilder sb = new StringBuilder();
        sb.append("\nTask Queue Size: ").append(taskQueue.size());
        for (int i = 0; i < workers.length; i++)
            sb.append("\nWorker ").append(i).append(" is ").append(workers[i].isWaiting() ? "Waiting." : "Running.");
        return sb.toString();
    }

    public synchronized void destroy() {
        for (PoolWorker w : workers) { w.stopWorker(); w = null; }
        taskQueue.clear();
    }

    private class PoolWorker extends Thread {
        private final int index;
        private boolean isRunning = true;
        private boolean isWaiting = true;

        PoolWorker(int index) { this.index = index; start(); }
        void stopWorker() { isRunning = false; }
        boolean isWaiting() { return isWaiting; }

        @Override
        public void run() {
            while (isRunning) {
                Task r = null;
                synchronized (taskQueue) {
                    while (taskQueue.isEmpty()) {
                        try { taskQueue.wait(20); }
                        catch (InterruptedException e) { logger.error(e); }
                    }
                    r = taskQueue.remove(0);
                }
                if (r != null) {
                    isWaiting = false;
                    try {
                        if (DEBUG) {
                            r.setBeginExecuteTime(new Date());
                            taskLogger.debug("Worker<" + index + "> start Task<" + r.getTaskId() + ">");
                        }
                        if (r.needExecuteImmediate()) new Thread(r).start();
                        else r.run();
                        if (DEBUG) {
                            r.setFinishTime(new Date());
                            taskLogger.debug("Worker<" + index + "> finish Task<" + r.getTaskId() + ">");
                        }
                    } catch (Exception e) { e.printStackTrace(); logger.error(e); }
                    isWaiting = true;
                }
            }
        }
    }
}

任務抽象基類

public abstract class Task implements Runnable {
    private Date generateTime, submitTime, beginExecuteTime, finishTime;
    private long taskId;

    public Task() { this.generateTime = new Date(); }

    @Override public void run() {
        // 範本:beginTransaction(); Task[] subtasks = taskCore(); commitTransaction(); batchAddTask(subtasks);
    }

    public abstract Task[] taskCore() throws Exception;
    protected abstract boolean useDb();
    protected abstract boolean needExecuteImmediate();
    public abstract String info();

    // Getter/Setter 略...
}

關鍵設計亮點

  • 單例模式確保全域唯一線程池。
  • 工作線程以 wait/notifyAll 機制高效等待任務,避免忙等待。
  • 支援立即執行模式(needExecuteImmediate)與批量提交。
  • 整合 Log4j 記錄任務提交、執行耗時、等待超時等診斷資訊。
  • 提供關閉鉤子(shutdown hook)確保 JVM 關閉時優雅釋放資源。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved