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

Java 線程池全解析:核心參數、四大預設池、異步任務實戰與 submit/execute 差異

     編輯:Java 綜合教學

為什麼需要線程池?

  • 頻繁創建/銷毀線程:開銷大(~1MB 棧內存/線程),易導致 OOM。
  • 無限制併發:CPU 競爭激烈,上下文切換開銷飆升,吞吐量反降。
  • 缺乏管理能力:無法定時、定期、限流、監控。

線程池解決:複用線程、控制併發度、提供豐富調度功能。

核心架構:ThreadPoolExecutor 七大參數

public ThreadPoolExecutor(
    int corePoolSize,           // 核心線程數(常駐)
    int maximumPoolSize,        // 最大線程數
    long keepAliveTime,         // 非核心線程閒置存活時間
    TimeUnit unit,              // 時間單位
    BlockingQueue<Runnable> workQueue, // 任務隊列
    ThreadFactory threadFactory,        // 線程工廠(命名、守護屬性)
    RejectedExecutionHandler handler    // 拒絕策略
)

執行流程

  1. 線程數 < corePoolSize → 創建核心線程執行。
  2. 線程數 ≥ corePoolSize → 任務入隊 workQueue。
  3. 隊列滿 && 線程數 < maximumPoolSize → 創建非核心線程執行。
  4. 隊列滿 && 線程數 ≥ maximumPoolSize → 執行 handler 拒絕策略。

常見隊列選型

隊列特性適用場景
ArrayBlockingQueue有界數組固定緩衝,需處理拒絕
LinkedBlockingQueue無界鏈表(默認 Integer.MAX_VALUE)任務量不可控,慎用(易 OOM)
SynchronousQueue零容量,直接移交線程數需彈性增減(如 newCachedThreadPool)
PriorityBlockingQueue優先級排序任務有輕重緩急

Executors 四大預設工廠方法(及避坑)

方法參數配置特點阿里規約/生產建議
newFixedThreadPool(n)core=max=n, LinkedBlockingQueue固定線程數,任務排隊✅ 推薦,但需評估隊列長度
newSingleThreadExecutor()core=max=1, LinkedBlockingQueue單線程串行,保證順序✅ 推薦,適用串行任務
newCachedThreadPool()core=0, max=Integer.MAX_VALUE, SynchronousQueue, keepAlive=60s彈性線程,閒置回收❌ 禁用:無界線程數極易 OOM
newScheduledThreadPool(n)core=n, max=Integer.MAX_VALUE, DelayedWorkQueue定時/周期任務⚠️ 謹慎,max 無界;建議自定義

實戰代碼示例

1. 固定線程池處理批量任務

ExecutorService pool = Executors.newFixedThreadPool(
    Runtime.getRuntime().availableProcessors() * 2 // CPU 密集型參考
);

for (int i = 0; i < 100; i++) {
    final int taskId = i;
    pool.execute(() -> {
        System.out.println("Task " + taskId + " by " + Thread.currentThread().getName());
    });
}
pool.shutdown(); // 優雅關閉

2. 定時/周期任務

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

// 延遲 3 秒執行一次
scheduler.schedule(() -> System.out.println("Delayed 3s"), 3, TimeUnit.SECONDS);

// 延遲 1 秒,每 3 秒執行一次
scheduler.scheduleAtFixedRate(() -> System.out.println("Periodic"), 1, 3, TimeUnit.SECONDS);

// 延遲 1 秒,上次結束後 3 秒再執行(固定延遲)
scheduler.scheduleWithFixedDelay(() -> System.out.println("FixedDelay"), 1, 3, TimeUnit.SECONDS);

submit() vs execute() 核心差異

維度execute(Runnable)submit(Runnable/Callable)
返回值voidFuture<T>(可獲取結果/異常)
任務類型只接受 Runnable接受 Runnable / Callable
異常處理拋給 Thread.UncaughtExceptionHandler封裝在 Future.get() 中拋 ExecutionException
取消支持無future.cancel(true) 可中斷

最佳實踐:需獲取結果/異常/取消 → submit(Callable);純火並忘 → execute(Runnable)。

線程池優雅關閉姿勢

pool.shutdown(); // 不再接受新任務,處理完隊列任務
try {
    if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
        pool.shutdownNow(); // 強制中斷正在執行的任務
        if (!pool.awaitTermination(60, TimeUnit.SECONDS))
            log.error("Pool did not terminate");
    }
} catch (InterruptedException ex) {
    pool.shutdownNow();
    Thread.currentThread().interrupt();
}

生產級自定義線程池模板

public class ThreadPoolConfig {
    public static ThreadPoolExecutor createBusinessPool(String poolName) {
        return new ThreadPoolExecutor(
            10, 20,
            60L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(500), // 有界隊列防 OOM
            new CustomThreadFactory(poolName), // 統一命名:biz-order-1
            new ThreadPoolExecutor.AbortPolicy() // 或 CallerRunsPolicy 降級
        );
    }
}

class CustomThreadFactory implements ThreadFactory {
    private final AtomicInteger seq = new AtomicInteger(0);
    private final String prefix;
    public CustomThreadFactory(String prefix) { this.prefix = prefix; }
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r, prefix + "-" + seq.incrementAndGet());
        t.setDaemon(false); // 業務線程非守護
        return t;
    }
}

總結

  1. 拒絕 Executors.xxx 無界實現,顯式構造 ThreadPoolExecutor 明確七大參數。
  2. 隊列必須有界,拒絕策略選 CallerRunsPolicy(降級由調用者執行)或自定義入庫重試。
  3. 線程命名規範化,便於日誌追蹤、Arthas 診斷。
  4. 監控指標:activeCount、queue.size、completedTaskCount、rejectCount。
  5. 掌握 Future 異步編程模式,配合 CompletableFuture(JDK 8+)構建非阻塞鏈路。

線程池是高併發系統的「心臟」,精細配置與持續觀測是穩定性的基石。

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