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

Java 多執行緒第三種建立方式:Callable、Future 與 CompletionService 實戰

     編輯:Java 相關知識

繼承 Thread、實作 Runnable 之外,Java 提供 Callable<V> 介面作為第三種建立執行緒方式。其 call() 方法支援回傳值與拋出檢查型例外,配合 Future<V> 與 CompletionService<V> 實現更強大的非同步程式設計模式。

一、Callable 與 Future 基礎應用

public class CallableFutureDemo {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        // 提交 Callable 任務,獲得 Future
        Future<String> future = executor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(20);  // 模擬耗時運算
                return "hi, amos";
            }
        });

        // 同步等待結果(阻塞直到完成)
        System.out.println("結果: " + future.get());

        // 可設定超時等待
        // future.get(1, TimeUnit.MILLISECONDS);

        executor.shutdown();
    }
}

關鍵差異點

  • 使用 submit() 而非 execute() 提交任務
  • call() 回傳值型別必須與 Future<V> 泛型一致
  • Future 提供 cancel()、isDone()、isCancelled() 等控制方法

二、CompletionService:非同步收割器模式

CompletionService 專為批量提交 Callable 任務設計,其 take() 方法會阻塞直到下一個完成的任務可用,類似「哪塊麥田先熟收割哪塊」。

public class CompletionServiceDemo {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        CompletionService<Integer> service = new ExecutorCompletionService<>(executor);

        // 提交 10 個隨機耗時任務
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            service.submit(() -> {
                Thread.sleep(new Random().nextInt(3000));
                return taskId;
            });
        }

        // 依完成順序獲取結果
        for (int i = 0; i < 10; i++) {
            System.out.println("已完成任務: " + service.take().get());
        }

        executor.shutdown();
    }
}

執行特性

  • 結果輸出順序 = 任務實際完成順序,非提交順序
  • 適用於「先完成先處理」的業務場景(如並行查詢、批次運算)
  • 避免 Future.get() 順序阻塞導致的效能損耗

進階應用建議

  1. 搭配 invokeAll() 批量提交並等待全部完成
  2. 使用 poll(timeout) 實現非阻塞輪詢
  3. 異常處理:get() 會拋出 ExecutionException 包裝任務異常
  4. 資源管理:務必在 finally 區塊關閉 ExecutorService
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved