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

J2SE 5.0 並發編程新紀元:Executor 框架與 java.util.concurrent 核心組件詳解

     編輯:Java 程式設計入門

前言:告別手動管理 Thread 的時代

J2SE 5.0 引入 java.util.concurrent 套件,提供高效能、高層級的執行緒管理框架,徹底改變 Java 多執行緒開發模式。本文深入解析 Executor 框架、執行緒池、排程任務、Future/Callable 等核心組件。

一、Executor 框架:任務提交與執行分離

核心介面

  • Executor:最簡單介面,單一方法 execute(Runnable),隱藏執行緒建立/排程細節。
  • ExecutorService:擴充生命週期管理(關閉、等待終止)、任務追蹤(Future)、批次提交(invokeAll/invokeAny)。
  • ScheduledExecutorService:支援定時、週期性任務排程。

同步 vs 非同步執行範例


// 同步執行(當前執行緒直接跑)
Executor syncExec = r -> r.run();

// 非同步執行(新執行緒啟動)
Executor asyncExec = r -> new Thread(r).start();

// 實務上直接使用 Executors 工廠
ExecutorService pool = Executors.newFixedThreadPool(4);
pool.execute(() -> System.out.println("任務在執行緒池中運行"));

二、ExecutorService:執行緒池與生命週期控制

常用工廠方法

方法特性適用場景
newFixedThreadPool(n)固定大小,無界隊列長期運行、任務量穩定的服務
newCachedThreadPool()可縮放,60秒空閒回收,無界隊列大量短生命週期任務
newSingleThreadExecutor()單執行緒,保證順序需序列化執行的任務(如日誌寫入)
newWorkStealingPool() (Java 8+)ForkJoinPool,工作窃取CPU 密集型、可並行化任務

關閉流程與最佳實踐

ExecutorService executor = Executors.newFixedThreadPool(3);

// 1. 停止接受新任務,已提交任務繼續執行
executor.shutdown();

try {
    // 2. 等待現有任務完成(設定超時)
    if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
        // 3. 強制關閉:嘗試中斷正在執行的任務
        List remaining = executor.shutdownNow();
        // 記錄未完成任務
    }
} catch (InterruptedException ex) {
    executor.shutdownNow();
    Thread.currentThread().interrupt(); // 保留中斷狀態
}

三、ScheduledExecutorService:精準排程利器

取代 Timer,支援多執行緒、異常處理、靈活排程:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

// 固定延遲:上一次執行結束後 delay 才開始下一次(適合不規律耗時任務)
scheduler.scheduleWithFixedDelay(() -> cleanup(), 1, 5, TimeUnit.MINUTES);

// 固定頻率:無論執行耗時,每 period 啟動一次(適合精準週期,如心跳)
ScheduledFuture beeper = scheduler.scheduleAtFixedRate(
    () -> System.out.println("beep"), 1, 5, TimeUnit.SECONDS);

// 單次延遲執行
scheduler.schedule(() -> shutdown(), 1, TimeUnit.HOURS);

// 取消排程
beeper.cancel(false); // false=不中斷正在執行的

四、Future 與 Callable:可獲取結果的非同步任務

ExecutorService es = Executors.newFixedThreadPool(4);

// Callable 有回傳值、可拋出異常
Callable task = () -> {
    Thread.sleep(2000);
    return 42;
};

Future future = es.submit(task);

// 非阻塞檢查
while (!future.isDone()) {
    System.out.println("處理其他業務...");
    Thread.sleep(500);
}

try {
    Integer result = future.get(); // 阻塞獲取結果
    System.out.println("結果:" + result);
} catch (ExecutionException e) {
    e.getCause().printStackTrace(); // 任務內部異常
}

// 可取消
Future f = es.submit(() -> { while(true); });
f.cancel(true); // true=中斷執行緒

五、進階組件速覽

  • CompletableFuture (Java 8+):非阻塞鏈式組合、異步回調、多任務編排(thenApply、allOf、anyOf)。
  • ForkJoinPool:分治演算法、遞歸並行(RecursiveTask/RecursiveAction)。
  • 並發集合:ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue 實作(ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue)。
  • 同步工具:CountDownLatch、CyclicBarrier、Semaphore、Phaser (Java 7+)、StampedLock (Java 8+)。

六、避坑指南

  1. 避免無界隊列 + 固定大小池:任務堆積導致 OOM。生產環境建議自定義 ThreadPoolExecutor 指定有界隊列 + 拒絕策略。
  2. 執行緒池大小設定:CPU 密集型 ≈ 核心數 + 1;IO 密集型 ≈ 核心數 * (1 + 平均等待/平均工作)。
  3. 提交任務時捕獲 RejectedExecutionException:隊列滿、池關閉時會拋出。
  4. 使用 ThreadLocal 隨執行緒池洩漏:任務結束時手動 remove(),或用 InheritableThreadLocal 謹慎。

結語

java.util.concurrent 是 Java 並發編程的基石。掌握 Executor 框架、執行緒池調優、Future/CompletableFuture 非同步編排、並發集合與同步工具,即可構建高效、穩定、可擴展的多執行緒系統。

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