最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java CompletableFuture 多任務(wù)編排方法實(shí)踐指南

 更新時間:2026年01月30日 12:00:51   作者:ljh_learn_from_base  
本文詳細(xì)介紹了CompletableFuture的核心方法,按功能分類整理,包括創(chuàng)建方法、完成處理方法、鏈?zhǔn)睫D(zhuǎn)換方法、組合方法、多Future聚合方法、狀態(tài)檢查方法,并結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧

CompletableFuture核心方法的系統(tǒng)對比,按功能分類整理

一、創(chuàng)建方法(靜態(tài)工廠)

方法返回值執(zhí)行線程特點(diǎn)示例
runAsync(Runnable)CompletableFuture<Void>ForkJoinPool.commonPool()無返回值runAsync(() -> log.info("ok"))
runAsync(Runnable, Executor)CompletableFuture<Void>指定線程池無返回值,自定義線程池runAsync(task, executor)
supplyAsync(Supplier<T>)CompletableFuture<T>ForkJoinPool.commonPool()有返回值supplyAsync(() -> fetchData())
supplyAsync(Supplier<T>, Executor)CompletableFuture<T>指定線程池有返回值,自定義線程池supplyAsync(() -> fetch(), executor)
completedFuture(U value)CompletableFuture<U>立即完成包裝已存在的值completedFuture(cachedValue)
failedFuture(Throwable)CompletableFuture<T>立即完成包裝異常(Java 9+)failedFuture(new TimeoutException())

二、完成處理方法(終結(jié)操作)

方法輸入輸出異常處理使用場景
whenComplete(BiConsumer<T,Throwable>)結(jié)果+異常原類型T異常繼續(xù)傳播資源清理、日志記錄
whenCompleteAsync(...)同上原類型T異常繼續(xù)傳播異步執(zhí)行清理
handle(BiFunction<T,Throwable,U>)結(jié)果+異常新類型U異常被轉(zhuǎn)換容錯恢復(fù)、默認(rèn)值
handleAsync(...)同上新類型U異常被轉(zhuǎn)換異步容錯處理
exceptionally(Function<Throwable,T>)異常原類型T僅異常時觸發(fā)異常降級處理
exceptionallyAsync(...)(Java 12+)異常原類型T僅異常時觸發(fā)異步異常處理

關(guān)鍵區(qū)別

// whenComplete:異常繼續(xù)拋,只能觀察
future.whenComplete((v, e) -> log.info("done")).join(); // 可能拋異常
// handle:異常被"吃掉",返回新值
future.handle((v, e) -> e != null ? "default" : v).join(); // 一定成功
// exceptionally:僅處理異常情況
future.exceptionally(e -> "error: " + e.getMessage()).join();

三、鏈?zhǔn)睫D(zhuǎn)換方法(中間操作)

方法前置結(jié)果轉(zhuǎn)換函數(shù)返回值異常時是否跳過
thenApply(Function<T,U>)TT → UCompletableFuture<U>? 跳過,傳異常
thenApplyAsync(...)TT → UCompletableFuture<U>? 跳過,傳異常
thenAccept(Consumer<T>)TT → voidCompletableFuture<Void>? 跳過,傳異常
thenAcceptAsync(...)TT → voidCompletableFuture<Void>? 跳過,傳異常
thenRun(Runnable)忽略() → voidCompletableFuture<Void>? 跳過,傳異常
thenRunAsync(...)忽略() → voidCompletableFuture<Void>? 跳過,傳異常

對比示例

supplyAsync(() -> "Hello")
    .thenApply(s -> s + " World")      // Hello World
    .thenAccept(System.out::println)    // 打印,返回Void
    .thenRun(() -> log.info("Done"));   // 不依賴前置結(jié)果

四、組合方法(合并多個Future

方法組合方式前置完成函數(shù)簽名輸出類型
thenCompose(Function<T,CF<U>>)扁平化鏈?zhǔn)?/td>等前一個T → CF<U>CF<U>
thenComposeAsync(...)同上同上同上CF<U>
thenCombine(CF<U>, BiFunction<T,U,V>)并行合并等兩個(T,U) → VCF<V>
thenCombineAsync(...)同上同上同上CF<V>
thenAcceptBoth(CF<U>, BiConsumer<T,U>)并行消費(fèi)等兩個(T,U) → voidCF<Void>
runAfterBoth(CF<?>, Runnable)并行運(yùn)行等兩個() → voidCF<Void>
applyToEither(CF<T>, Function<T,U>)競速取快任一個T → UCF<U>
acceptEither(CF<T>, Consumer<T>)競速消費(fèi)任一個T → voidCF<Void>
runAfterEither(CF<?>, Runnable)競速運(yùn)行任一個() → voidCF<Void>

場景對比

// thenCompose:串行依賴(扁平化避免嵌套)
fetchUserId().thenCompose(id -> fetchUserDetail(id)); // CF<User>
// thenCombine:并行聚合
CompletableFuture<String> f1 = fetchPrice();
CompletableFuture<String> f2 = fetchStock();
f1.thenCombine(f2, (price, stock) -> "Price:" + price + ", Stock:" + stock);
// applyToEither:超時降級
fetchFromCache()
    .applyToEither(fetchFromDB(), result -> result);  // 哪個快用哪個

五、多Future聚合方法(靜態(tài)方法)

方法輸入觸發(fā)條件輸出特點(diǎn)
allOf(CF<?>... cfs)多個CF全部完成CF<Void>等待全部,無返回值
anyOf(CF<?>... cfs)多個CF任一個完成CF<Object>競速,返回最快的結(jié)果
join()--T阻塞獲取結(jié)果,拋非檢查異常
get()--T阻塞獲取,拋檢查異常
get(long, TimeUnit)--T帶超時的阻塞獲取

allOf vs anyOf

CompletableFuture<String> f1 = asyncTask1();
CompletableFuture<String> f2 = asyncTask2();
CompletableFuture<String> f3 = asyncTask3();
// allOf:等全部完成,再收集結(jié)果
CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3);
all.thenRun(() -> {
    String r1 = f1.join(); // 此時都已完成,直接取
    String r2 = f2.join();
    String r3 = f3.join();
});
// anyOf:取最快完成的
CompletableFuture<Object> any = CompletableFuture.anyOf(f1, f2, f3);
any.thenAccept(result -> {
    // result是最快完成的那個(類型是Object,需強(qiáng)轉(zhuǎn))
});

六、狀態(tài)檢查方法

方法返回值說明注意
isDone()boolean是否已完成(正常/異常/取消)不區(qū)分成功失敗
isCancelled()boolean是否被取消-
isCompletedExceptionally()boolean是否異常完成Java 8+
getNow(T valueIfAbsent)T立即獲取,未完成返回默認(rèn)值非阻塞
complete(T value)boolean強(qiáng)制完成(如果未完成)只能調(diào)用一次
completeExceptionally(Throwable)boolean強(qiáng)制異常完成只能調(diào)用一次
cancel(boolean)boolean取消任務(wù)可能不中斷執(zhí)行線程

七、方法命名規(guī)律總結(jié)

關(guān)鍵詞含義示例
Async異步執(zhí)行(新線程/線程池)thenApplyAsync
Apply有返回值,轉(zhuǎn)換類型thenApply(T→U)
Accept無返回值,消費(fèi)結(jié)果thenAccept(T→void)
Run無輸入無輸出,純副作用thenRun(→void)
Compose扁平化鏈?zhǔn)剑ū苊釩F<CF<T>>)thenCompose(T→CF<U>)
Combine合并兩個并行結(jié)果thenCombine(CF<U>, (T,U)→V)
Either兩個中任一個完成即觸發(fā)applyToEither
Both兩個都完成才觸發(fā)runAfterBoth
Handle處理結(jié)果或異常,可轉(zhuǎn)換handle((T,Throwable)→U)
Exceptionally僅處理異常情況exceptionally(Throwable→T)

八、快速選擇指南

需要創(chuàng)建異步任務(wù)?
    ├── 無返回值 → runAsync
    └── 有返回值 → supplyAsync
需要在完成后做操作?
    ├── 要轉(zhuǎn)換結(jié)果 → thenApply
    ├── 只消費(fèi)結(jié)果 → thenAccept
    └── 不依賴結(jié)果 → thenRun
需要處理異常?
    ├── 只清理資源,異常繼續(xù)拋 → whenComplete
    ├── 異常轉(zhuǎn)默認(rèn)值 → handle
    └── 異常降級 → exceptionally
需要組合多個Future?
    ├── 串行依賴(A→B)→ thenCompose
    ├── 并行聚合(A+B→C)→ thenCombine
    ├── 多個等全部 → allOf
    └── 多個取最快 → anyOf

掌握這個,可以覆蓋 90% 的 CompletableFuture 使用場景。

九:實(shí)戰(zhàn)代碼

import java.util.concurrent.*;
/**
 * CompletableFuture 全方法指南示例
 * 涵蓋:創(chuàng)建、轉(zhuǎn)換、組合、異常處理、聚合等所有核心操作
 */
public class CompletableFutureGuide {
    private final ExecutorService executor = Executors.newFixedThreadPool(4);
    // ==================== 一、創(chuàng)建方法 ====================
    /**
     * 指南:無返回值異步任務(wù),不使用默認(rèn)線程池
     * 【除了使用自定義線程池外,還可以使用CompletableFuture的join和get方法】
     * CompletableFuture,沒有指定自定義線程池的時候【可以把executor去掉試一下】,創(chuàng)建的居然是守護(hù)線程。
     * 當(dāng)只有守護(hù)線程和主線程【非守護(hù)線程】時,所有非守護(hù)程結(jié)束,守護(hù)線程也結(jié)束,jvm直接退出結(jié)束,等不了2秒。【子線程執(zhí)行完畢】這句話永遠(yuǎn)不會執(zhí)行
     */
    public void demoRunAsync() {
        System.out.println("=== runAsync ===");
        CompletableFuture.runAsync(() -> {
            // System.out.println("當(dāng)前線程是否是守護(hù)線程:"+Thread.currentThread().isDaemon());
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("demoRunAsync執(zhí)行日志記錄,線程: " + Thread.currentThread().getName());
        }, this.executor).whenComplete((result, exception) -> {
            //子線程執(zhí)行完畢
            System.out.println("demoRunAsync子線程執(zhí)行完畢");
        });
        //future.join(); // 等待子線程完成
        System.out.println("=== demoRunAsync主線程結(jié)束,等待子線程執(zhí)行結(jié)束===");
    }
    /**
     * 指南:無返回值異步任務(wù),使用自定義線程池
     */
    public void demoRunAsyncWithExecutor() {
        System.out.println("=== runAsync + Executor ===");
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            System.out.println("自定義線程池執(zhí)行,線程: " + Thread.currentThread().getName());
        }, executor);
        future.join();
    }
    /**
     * 指南:有返回值異步任務(wù),使用默認(rèn)線程池
     */
    public void demoSupplyAsync() {
        System.out.println("=== supplyAsync ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "從數(shù)據(jù)庫獲取的數(shù)據(jù)";
        });
        System.out.println("結(jié)果: " + future.join());
    }
    /**
     * 指南:有返回值異步任務(wù),使用自定義線程池
     */
    public void demoSupplyAsyncWithExecutor() {
        System.out.println("=== supplyAsync + Executor ===");
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("計算中... 線程: " + Thread.currentThread().getName());
            return 42;
        }, executor);
        System.out.println("計算結(jié)果: " + future.join());
    }
    /**
     * 指南:包裝已存在的值(立即完成)
     * <pre>
     * // 使用場景:從緩存獲取結(jié)果(如果緩存命中)
     * public CompletableFuture<String> getFromCache(String key) {
     *     String cached = cache.get(key);
     *     if (cached != null) {
     *         return CompletableFuture.completedFuture(cached); // 緩存命中,直接返回已完成的結(jié)果
     *     }
     *     // 緩存未命中,需要異步加載
     *     return CompletableFuture.supplyAsync(() -> loadFromDb(key));
     * }
     * </pre>
     */
    public void demoCompletedFuture() {
        System.out.println("=== completedFuture ===");
        String cachedValue = "緩存的用戶信息";
        CompletableFuture<String> future = CompletableFuture.completedFuture(cachedValue);
        // 立即完成,不會異步執(zhí)行
        System.out.println("是否完成: " + future.isDone());
        System.out.println("值: " + future.join());
    }
    // ==================== 二、完成處理方法 ====================
    /**
     * 指南:whenComplete - 只觀察不干預(yù),異常繼續(xù)傳播
     * 場景:資源清理、日志記錄
     */
    public void demoWhenComplete() {
        System.out.println("=== whenComplete ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            if (Math.random() > 0.5) throw new RuntimeException("隨機(jī)失敗");
            return "成功";
        });
        CompletableFuture<String> result = future.whenComplete((value, exception) -> {
            // whenComplete只能觀察,不能改變結(jié)果,需要改變結(jié)果的,要使用handle方法
            System.out.println("whenComplete 觀察到: " +
                    (exception != null ? "異常" : "值=" + value));
        });
        try {
            System.out.println("最終結(jié)果: " + result.join());
        } catch (Exception e) {
            System.out.println("join() 拋出異常: " + e.getCause().getMessage());
        }
    }
    /**
     * 指南:whenCompleteAsync - 異步執(zhí)行清理
     */
    public void demoWhenCompleteAsync() {
        System.out.println("=== whenCompleteAsync ===");
        CompletableFuture.supplyAsync(() -> "任務(wù)完成")
                .whenCompleteAsync((v, e) -> {
                    sleep(200);
                    System.out.println("異步清理,線程: " + Thread.currentThread().getName());
                }, executor)
                .join();
        System.out.println("=== whenCompleteAsync 結(jié)束===");
    }
    /**
     * 指南:handle - 轉(zhuǎn)換結(jié)果,異常可被修復(fù)
     * 注意與whenComplete方法的區(qū)別:whenComplete不能改變返回值
     * 場景:容錯恢復(fù)、提供默認(rèn)值
     */
    public void demoHandle() {
        System.out.println("=== handle ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException("服務(wù)不可用");
        });
        CompletableFuture<String> result = future.handle((value, exception) -> {
            // 可以返回新值,改變結(jié)果
            if (exception != null) {
                System.out.println("handle 修復(fù)異常,返回默認(rèn)值");
                return "默認(rèn)數(shù)據(jù)(降級)";
            }
            return value + "(加工后)";
        });
        // 不會拋異常,因?yàn)橐驯籬andle處理
        System.out.println("最終結(jié)果: " + result.join());
    }
    /**
     * 指南:handleAsync - 異步容錯處理
     */
    public void demoHandleAsync() {
        System.out.println("=== handleAsync ===");
        // CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
        CompletableFuture.completedFuture(100)
                .handleAsync((v, e) -> {
                    System.out.println("異步處理結(jié)果,線程: " + Thread.currentThread().getName());
                    return v != null ? v * 2 : 0;
                }, executor)
                .thenAccept(System.out::println)
                .join();
    }
    /**
     * 指南:exceptionally - 僅處理異常情況
     * 場景:異常降級處理
     */
    public void demoExceptionally() {
        System.out.println("=== exceptionally ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException("數(shù)據(jù)庫連接失敗");
        });
        CompletableFuture<String> result = future.exceptionally(ex -> {
            System.out.println("exceptionally 捕獲: " + ex.getMessage());
            return "從緩存讀取的備份數(shù)據(jù)";
        });
        System.out.println("結(jié)果: " + result.join());
    }
    // ==================== 三、鏈?zhǔn)睫D(zhuǎn)換方法 ====================
    /**
     * 指南:thenApply - 轉(zhuǎn)換結(jié)果類型 T → U
     */
    public void demoThenApply() {
        System.out.println("=== thenApply ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "123")
                .thenApply(Integer::parseInt)           // String → Integer
                .thenApply(n -> n * 2)                   // Integer → Integer
                .thenApply(String::valueOf);             // Integer → String
        System.out.println("轉(zhuǎn)換結(jié)果: " + future.join());
    }
    /**
     * 指南:thenApplyAsync - 異步轉(zhuǎn)換
     */
    public void demoThenApplyAsync() {
        System.out.println("=== thenApplyAsync ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
                .thenApplyAsync(s -> {
                    System.out.println("異步轉(zhuǎn)換,線程: " + Thread.currentThread().getName());
                    return s.toUpperCase();
                }, executor);
        System.out.println(future.join());
    }
    /**
     * 指南:thenAccept - 消費(fèi)結(jié)果,無返回值
     */
    public void demoThenAccept() {
        System.out.println("=== thenAccept ===");
        CompletableFuture.supplyAsync(() -> "訂單創(chuàng)建成功")
                .thenAccept(msg -> System.out.println("發(fā)送通知: " + msg))
                .join(); // 返回Void
    }
    /**
     * 指南:thenAcceptAsync - 異步消費(fèi)
     */
    public void demoThenAcceptAsync() {
        System.out.println("=== thenAcceptAsync ===");
        CompletableFuture.supplyAsync(() -> "用戶登錄")
                .thenAcceptAsync(event -> {
                    System.out.println("異步記錄日志,線程: " + Thread.currentThread().getName());
                }, executor)
                .join();
    }
    /**
     * 指南:thenRun - 不依賴前置結(jié)果,純副作用
     */
    public void demoThenRun() {
        System.out.println("=== thenRun ===");
        CompletableFuture.supplyAsync(() -> "步驟1完成")
                .thenRun(() -> System.out.println("執(zhí)行步驟2(不依賴步驟1結(jié)果)"))
                .thenRun(() -> System.out.println("執(zhí)行步驟3"))
                .join();
    }
    /**
     * 指南:thenRunAsync - 異步執(zhí)行副作用
     */
    public void demoThenRunAsync() {
        System.out.println("=== thenRunAsync ===");
        CompletableFuture.supplyAsync(() -> "任務(wù)")
                .thenRunAsync(() -> {
                    System.out.println("異步清理資源,線程: " + Thread.currentThread().getName());
                }, executor)
                .join();
    }
    // ==================== 四、組合方法 ====================
    /**
     * 指南:thenCompose - 扁平化鏈?zhǔn)?,避?CF<CF<T>>
     * 場景:串行依賴,如先取ID再取詳情
     */
    public void demoThenCompose() {
        System.out.println("=== thenCompose ===");
        CompletableFuture<String> future = fetchUserId()
                .thenCompose(this::fetchUserDetail); // 返回 CF<User> 被扁平化為 CF<User>
        System.out.println("用戶信息: " + future.join());
    }
    private CompletableFuture<String> fetchUserId() {
        return CompletableFuture.supplyAsync(() -> "user_123");
    }
    private CompletableFuture<String> fetchUserDetail(String userId) {
        return CompletableFuture.supplyAsync(() -> "詳情 of " + userId);
    }
    /**
     * 指南:thenComposeAsync - 異步扁平化
     */
    public void demoThenComposeAsync() {
        System.out.println("=== thenComposeAsync ===");
        fetchUserId().thenComposeAsync(id -> {
            System.out.println("異步獲取詳情,線程: " + Thread.currentThread().getName());
            return fetchUserDetail(id);
        }, executor).join();
    }
    /**
     * 指南:thenCombine - 并行合并兩個結(jié)果 (T, U) → V
     * 場景:同時查詢價格和庫存,合并展示
     */
    public void demoThenCombine() {
        System.out.println("=== thenCombine ===");
        CompletableFuture<String> priceFuture = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "¥199";
        });
        CompletableFuture<Integer> stockFuture = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return 50;
        });
        CompletableFuture<String> result = priceFuture.thenCombine(stockFuture,
                (price, stock) -> "價格:" + price + ", 庫存:" + stock + "件"
        );
        System.out.println(result.join());
    }
    /**
     * 指南:thenCombineAsync - 異步合并
     */
    public void demoThenCombineAsync() {
        System.out.println("=== thenCombineAsync ===");
        CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> "A");
        CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> "B");
        f1.thenCombineAsync(f2, (a, b) -> {
            System.out.println("異步合并,線程: " + Thread.currentThread().getName());
            return a + "-" + b;
        }, executor).thenAccept(System.out::println).join();
    }
    /**
     * 指南:thenAcceptBoth - 并行消費(fèi)兩個結(jié)果
     */
    public void demoThenAcceptBoth() {
        System.out.println("=== thenAcceptBoth ===");
        CompletableFuture<String> orderFuture = CompletableFuture.supplyAsync(() -> "訂單123");
        CompletableFuture<String> paymentFuture = CompletableFuture.supplyAsync(() -> "支付成功");
        orderFuture.thenAcceptBoth(paymentFuture, (order, payment) -> {
            System.out.println("訂單: " + order);
            System.out.println("支付: " + payment);
            System.out.println("可以發(fā)貨了!");
        }).join();
    }
    /**
     * 指南:runAfterBoth - 兩個都完成后執(zhí)行Runnable
     */
    public void demoRunAfterBoth() {
        System.out.println("=== runAfterBoth ===");
        CompletableFuture<String> cacheUpdate = CompletableFuture.supplyAsync(() -> {
            System.out.println("更新緩存");
            return "done";
        });
        CompletableFuture<String> dbUpdate = CompletableFuture.supplyAsync(() -> {
            System.out.println("更新數(shù)據(jù)庫");
            return "done";
        });
        cacheUpdate.runAfterBoth(dbUpdate, () -> {
            System.out.println("緩存和數(shù)據(jù)庫都更新完畢,發(fā)送通知");
        }).join();
    }
    /**
     * 指南:applyToEither - 競速,取最快結(jié)果 T → U
     * 場景:超時降級,多個服務(wù)商競速
     */
    public void demoApplyToEither() {
        System.out.println("=== applyToEither ===");
        CompletableFuture<String> localCache = CompletableFuture.supplyAsync(() -> {
            sleep(50); // 快
            return "緩存結(jié)果";
        });
        CompletableFuture<String> remoteService = CompletableFuture.supplyAsync(() -> {
            sleep(200); // 慢
            return "遠(yuǎn)程結(jié)果";
        });
        CompletableFuture<String> result = localCache.applyToEither(remoteService,
                winner -> "最快返回的是: " + winner
        );
        System.out.println(result.join());
    }
    /**
     * 指南:acceptEither - 競速消費(fèi)
     */
    public void demoAcceptEither() {
        System.out.println("=== acceptEither ===");
        CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "服務(wù)A";
        });
        CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> {
            sleep(50);
            return "服務(wù)B";
        });
        f1.acceptEither(f2, winner -> {
            System.out.println("使用 " + winner + " 的結(jié)果");
        }).join();
    }
    /**
     * 指南:runAfterEither - 任一個完成就執(zhí)行
     */
    public void demoRunAfterEither() {
        System.out.println("=== runAfterEither ===");
        CompletableFuture<String> backup = CompletableFuture.supplyAsync(() -> {
            sleep(500);
            return "備份完成";
        });
        CompletableFuture<String> primary = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "主任務(wù)完成";
        });
        backup.runAfterEither(primary, () -> {
            System.out.println("至少有一個完成了,繼續(xù)下一步");
        }).join();
    }
    // ==================== 五、多Future聚合方法 ====================
    /**
     * 指南:allOf - 等待全部完成
     * 場景:批量操作后統(tǒng)一處理
     */
    public void demoAllOf() {
        System.out.println("=== allOf ===");
        CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "任務(wù)1";
        });
        CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> {
            sleep(200);
            return "任務(wù)2";
        });
        CompletableFuture<String> f3 = CompletableFuture.supplyAsync(() -> {
            sleep(150);
            return "任務(wù)3";
        });
        CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3);
        all.thenRun(() -> {
            // 全部完成后收集結(jié)果
            String r1 = f1.join();
            String r2 = f2.join();
            String r3 = f3.join();
            System.out.println("全部完成: " + r1 + ", " + r2 + ", " + r3);
        }).join();
    }
    /**
     * 指南:anyOf - 取最快完成
     * 場景:多源查詢,誰快用誰
     */
    public void demoAnyOf() {
        System.out.println("=== anyOf ===");
        CompletableFuture<Object> any = CompletableFuture.anyOf(
                CompletableFuture.supplyAsync(() -> {
                    sleep(300);
                    return "慢服務(wù)";
                }),
                CompletableFuture.supplyAsync(() -> {
                    sleep(50);
                    return "快服務(wù)";
                }),
                CompletableFuture.supplyAsync(() -> {
                    sleep(200);
                    return "中服務(wù)";
                })
        );
        System.out.println("最快的是: " + any.join());
    }
    /**
     * 指南:join vs get
     */
    public void demoJoinVsGet() throws Exception {
        System.out.println("=== join vs get ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "ok");
        // join(): 拋出非檢查異常,可直接使用
        String result1 = future.join();
        // get(): 拋出檢查異常,需要try-catch或throws
        String result2 = future.get();
        // get(timeout): 帶超時
        String result3 = future.get(1, TimeUnit.SECONDS);
        System.out.println("join: " + result1 + ", get: " + result2);
    }
    // ==================== 六、狀態(tài)檢查方法 ====================
    /**
     * 指南:狀態(tài)檢查方法
     */
    public void demoStatusCheck() {
        System.out.println("=== 狀態(tài)檢查 ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "done";
        });
        System.out.println("創(chuàng)建后立即檢查:");
        System.out.println("  isDone: " + future.isDone());
        System.out.println("  isCancelled: " + future.isCancelled());
        System.out.println("  isCompletedExceptionally: " + future.isCompletedExceptionally());
        future.join(); // 等待完成
        System.out.println("完成后檢查:");
        System.out.println("  isDone: " + future.isDone());
    }
    /**
     * 指南:getNow - 立即獲取,未完成返回默認(rèn)值
     */
    public void demoGetNow() {
        System.out.println("=== getNow ===");
        CompletableFuture<String> incomplete = new CompletableFuture<>();
        // 未完成,返回默認(rèn)值
        String value = incomplete.getNow("默認(rèn)值");
        System.out.println("未完成時: " + value);
        // 完成后
        incomplete.complete("實(shí)際值");
        value = incomplete.getNow("默認(rèn)值");
        System.out.println("完成后: " + value);
    }
    /**
     * 指南:complete - 強(qiáng)制完成
     */
    public void demoComplete() {
        System.out.println("=== complete ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            sleep(1000); // 長時間任務(wù)
            return "原始結(jié)果";
        });
        // 強(qiáng)制提前完成
        boolean success = future.complete("強(qiáng)制結(jié)果");
        System.out.println("強(qiáng)制完成是否成功: " + success);
        System.out.println("結(jié)果: " + future.join());
        // 再次complete無效
        boolean failed = future.complete("新結(jié)果");
        System.out.println("再次complete: " + failed);
    }
    /**
     * 指南:completeExceptionally - 強(qiáng)制異常完成
     */
    public void demoCompleteExceptionally() {
        System.out.println("=== completeExceptionally ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            sleep(1000);
            return "不會返回";
        });
        // 強(qiáng)制標(biāo)記為異常
        future.completeExceptionally(new CancellationException("用戶取消"));
        try {
            future.join();
        } catch (CompletionException e) {
            System.out.println("異常: " + e.getCause().getClass().getSimpleName());
        }
    }
    /**
     * 指南:cancel - 取消任務(wù)
     */
    public void demoCancel() {
        System.out.println("=== cancel ===");
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                // 模擬長時間運(yùn)行
                if (Math.random() > 0.99) break;
            }
            return "完成";
        });
        sleep(10); // 讓任務(wù)啟動
        boolean cancelled = future.cancel(true); // true=嘗試中斷線程
        System.out.println("取消結(jié)果: " + cancelled);
        System.out.println("isCancelled: " + future.isCancelled());
        System.out.println("isDone: " + future.isDone());
    }
    // ==================== 綜合實(shí)戰(zhàn)示例 ====================
    /**
     * 綜合場景:訂單處理流程
     * 展示多方法組合使用
     */
    public void demoOrderProcess() {
        System.out.println("=== 綜合實(shí)戰(zhàn):訂單處理 ===");
        // 1. 創(chuàng)建訂單(supplyAsync)
        CompletableFuture<String> orderFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("1. 創(chuàng)建訂單");
            return "ORDER_123";
        });
        // 2. 同時執(zhí)行:扣庫存 + 扣款(thenCombine)
        CompletableFuture<String> inventoryFuture = orderFuture.thenApply(order -> {
            System.out.println("2a. 扣減庫存: " + order);
            return "庫存OK";
        });
        CompletableFuture<String> paymentFuture = orderFuture.thenCompose(order ->
                CompletableFuture.supplyAsync(() -> {
                    System.out.println("2b. 處理支付: " + order);
                    return "支付OK";
                })
        );
        // 3. 兩者都完成才發(fā)貨(thenAcceptBoth)
        CompletableFuture<Void> shippingFuture = inventoryFuture.thenAcceptBoth(paymentFuture,
                (inv, pay) -> System.out.println("3. 發(fā)貨!(" + inv + ", " + pay + ")")
        );
        // 4. 異常處理:如果失敗發(fā)送通知(exceptionally)
        CompletableFuture<String> result = shippingFuture
                .thenApply(v -> "訂單完成")
                .exceptionally(ex -> {
                    System.out.println("錯誤: " + ex.getMessage());
                    return "訂單失敗";
                });
        // 5. 最終清理(whenComplete)
        result.whenComplete((res, ex) -> {
            System.out.println("4. 最終狀態(tài): " + res);
            System.out.println("5. 清理資源");
        }).join();
    }
    // ==================== 輔助方法 ====================
    private void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    public void shutdown() {
        executor.shutdown();
    }
    // ==================== Main ====================
    public static void main(String[] args) throws Exception {
        CompletableFutureGuide guide = new CompletableFutureGuide();
        // 一、創(chuàng)建方法
        guide.demoRunAsync();
        guide.demoRunAsyncWithExecutor();
        guide.demoSupplyAsync();
        guide.demoSupplyAsyncWithExecutor();
        guide.demoCompletedFuture();
        // 二、完成處理
        guide.demoWhenComplete();
        guide.demoWhenCompleteAsync();
        guide.demoHandle();
        guide.demoHandleAsync();
        guide.demoExceptionally();
        // 三、鏈?zhǔn)睫D(zhuǎn)換
        guide.demoThenApply();
        guide.demoThenApplyAsync();
        guide.demoThenAccept();
        guide.demoThenAcceptAsync();
        guide.demoThenRun();
        guide.demoThenRunAsync();
        // 四、組合方法【組合其它CompletableFuture】
        guide.demoThenCompose();
        guide.demoThenComposeAsync();
        guide.demoThenCombine();
        guide.demoThenCombineAsync();
        guide.demoThenAcceptBoth();
        guide.demoRunAfterBoth();
        guide.demoApplyToEither();
        guide.demoAcceptEither();
        guide.demoRunAfterEither();
        // 五、聚合方法
        guide.demoAllOf();
        guide.demoAnyOf();
        guide.demoJoinVsGet();
        // 六、狀態(tài)檢查
        guide.demoStatusCheck();
        guide.demoGetNow();
        guide.demoComplete();
        guide.demoCompleteExceptionally();
        guide.demoCancel();
        // 綜合實(shí)戰(zhàn)
        guide.demoOrderProcess();
        guide.shutdown();
        System.out.println("\n所有演示完成!");
    }
}

到此這篇關(guān)于Java CompletableFuture 多任務(wù)編排方法實(shí)踐指南的文章就介紹到這了,更多相關(guān)Java CompletableFuture 多任務(wù)編排內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud實(shí)現(xiàn)SSO 單點(diǎn)登錄的示例代碼

    SpringCloud實(shí)現(xiàn)SSO 單點(diǎn)登錄的示例代碼

    作為分布式項(xiàng)目,單點(diǎn)登錄是必不可少的,這篇文章主要介紹了SpringCloud實(shí)現(xiàn)SSO 單點(diǎn)登錄的示例代碼,非常具有實(shí)用價值,需要的朋友可以參考下
    2019-01-01
  • Java設(shè)計模式七大原則之依賴倒置原則詳解

    Java設(shè)計模式七大原則之依賴倒置原則詳解

    依賴倒轉(zhuǎn)原則,即:上層模塊不應(yīng)該依賴底層模塊,它們都應(yīng)該依賴于抽象,抽象不應(yīng)該依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴于抽象。本文將詳細(xì)介紹Java設(shè)計模式七大原則之一的依賴倒置原則,需要的可以參考一下
    2022-02-02
  • Mybatis使用Collection屬性的示例代碼

    Mybatis使用Collection屬性的示例代碼

    本文主要介紹了Mybatis使用Collection屬性的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 解讀springboot配置mybatis的sql執(zhí)行超時時間(mysql)

    解讀springboot配置mybatis的sql執(zhí)行超時時間(mysql)

    這篇文章主要介紹了解讀springboot配置mybatis的sql執(zhí)行超時時間(mysql),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Java實(shí)現(xiàn)多個wav文件合成一個的方法示例

    Java實(shí)現(xiàn)多個wav文件合成一個的方法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)多個wav文件合成一個的方法,涉及java文件流讀寫、編碼轉(zhuǎn)換、解析等相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • IDEA 2022 CPU占用100%的問題及解決方法

    IDEA 2022 CPU占用100%的問題及解決方法

    這篇文章主要介紹了IDEA 2022 CPU占用100%問題及解決方法,其實(shí)解決方法很簡單,只需要禁用三個插件然后重啟idea即可成功解決,需要的朋友可以參考下本文
    2022-08-08
  • Java將Word、Excel、PDF和PPT轉(zhuǎn)換為OFD格式的詳細(xì)步驟

    Java將Word、Excel、PDF和PPT轉(zhuǎn)換為OFD格式的詳細(xì)步驟

    OFD是一種依據(jù)中國國家標(biāo)準(zhǔn)制定的電子文檔格式,廣泛應(yīng)用于政務(wù)辦公、金融服務(wù)、法律事務(wù)及檔案管理等領(lǐng)域,本文將介紹如何使用 Java 將 Word、Excel、PDF 和 PowerPoint 文檔轉(zhuǎn)換為 OFD 格式,含詳細(xì)實(shí)現(xiàn)步驟介紹與代碼示例,需要的朋友可以參考下
    2025-09-09
  • java數(shù)學(xué)歸納法非遞歸求斐波那契數(shù)列的方法

    java數(shù)學(xué)歸納法非遞歸求斐波那契數(shù)列的方法

    這篇文章主要介紹了java數(shù)學(xué)歸納法非遞歸求斐波那契數(shù)列的方法,涉及java非遞歸算法的使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • Java基礎(chǔ)之命名規(guī)范的詳解

    Java基礎(chǔ)之命名規(guī)范的詳解

    這篇文章主要介紹了Java基礎(chǔ)之命名規(guī)范的詳解,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)Java基礎(chǔ)的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Mybatis之Select Count(*)的獲取返回int的值操作

    Mybatis之Select Count(*)的獲取返回int的值操作

    這篇文章主要介紹了Mybatis之Select Count(*)的獲取返回int的值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11

最新評論

平塘县| 门源| 景宁| 宿州市| 景泰县| 义乌市| 东莞市| 岗巴县| 鹤庆县| 桃源县| 建宁县| 永康市| 弋阳县| 西丰县| 外汇| 治多县| 钟山县| 武平县| 张北县| 张掖市| 濉溪县| 金平| 罗平县| 五河县| 元谋县| 余姚市| 丹寨县| 汾阳市| 赤壁市| 米脂县| 山东省| 仪陇县| 太谷县| 潍坊市| 色达县| 霍州市| 当涂县| 恩施市| 南郑县| 澳门| 侯马市|