【異步函數式編程】CompletableFuture用法(二)

繼上章節(傳送門>>>),本章繼續介紹CompletableFuture其餘方法的使用。java

public static void main(String[] args) throws Exception {
    // 6. 回調2.0【whenComplete,handle】
    CompletableFuture<String> cf4 = CompletableFuture.supplyAsync(() -> {
        System.out.println("6.業務過程=" + 1 / 1);
        // System.out.println("6.業務過程=" + 1 / 0);
        return "cf4正常執行返回";
    }).whenComplete((result, exce) -> {
        if (null != exce) {
            // exce.printStackTrace();
            System.out.println("異常信息=" + exce.getMessage());
        } else {
            System.out.println("6.回調2.0正常執行返回");
        }
    });
    System.out.println(cf4.get());
    /** * 注: 和以前回調應用場景的區別 * 1.cf4任務是正常執行的,cf4.get()的結果就是cf4執行的結果 * 2.cf4任務是執行異常的,則cf4.get()會拋出異常 * * handle與whenComplete用法相似,區別: * 1:handle有返回值,whenComplete無返回值 * 2:handle有返回值且與cf4自身的返回無任何關係 */

    // 7.組合處理(1)【thenCombine、thenAcceptBoth、runAfterBoth】
    /** * 三個方法都是將兩個CompletableFuture組合起來,兩個都正常執行完了纔會執行某個任務 * 區別: * 1:thenCombine會將兩個任務的返回值做爲入參傳遞到目標方法中,且目標方法有返回值 * 2:thenAcceptBoth一樣將兩個任務的返回值做爲目標方法入參,但目標方法無返回值 * 3:runAfterBoth沒有入參,也沒有返回值 */
    CompletableFuture<String> cf5_1 = CompletableFuture.supplyAsync(() -> {
        // 任務1
        return "cf5_1返回";
    });
    CompletableFuture<String> cf5_2 = CompletableFuture.supplyAsync(() -> {
        // 任務2
        return "cf5_2返回";
    });

    CompletableFuture<String> cf5_thenCombine = cf5_1.thenCombine(cf5_2, (a, b) -> {
        // 有返回
        return "7.組合處理【thenCombine】=" + a + " -- " + b;
    });
    System.out.println(cf5_thenCombine.get());

    CompletableFuture<Void> cf5_thenAcceptBoth = cf5_1.thenAcceptBoth(cf5_2, (a, b) -> {
        // 無返回
        System.out.println("7.組合處理【thenAcceptBoth】=" + a + " -- " + b);
    });
    cf5_thenAcceptBoth.get();
    CompletableFuture<Void> cf5_runAfterBoth = cf5_1.runAfterBoth(cf5_2, () -> {
        // 無入參,無返回
        System.out.println("7.組合處理【runAfterBoth】=" + "無入參,無返回");
    });
    cf5_runAfterBoth.get();

    // 7.組合處理(2)【applyToEither、acceptEither、runAfterEither】
    /** * 三個方法都是將兩個CompletableFuture組合起來,只要其中一個執行完了就會執行目標任務 * 區別: * 1:applyToEither會將已經執行完成的任務的執行結果做爲方法入參,並有返回值; * 2:acceptEither一樣將已經執行完成的任務的執行結果做爲方法入參,可是沒有返回值 * 3:runAfterEither沒有方法入參,也沒有返回值 */
    // 7.組合處理(1)和7.組合處理(2)的區別在於,執行目標任務的前提,前者必須所有正常執行,後者有一個執行完成

    // 8.【allOf、anyOf】
    CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        return "Task1";
    });
    CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
        }
        return "Task2";
    });
    CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(2500);
        } catch (InterruptedException e) {
        }
        return "Task3";
    });

    // 能夠相似實現countdownLatch的功能,實現阻塞線程,等待子任務執行完成
    CompletableFuture<Void> cf6 = CompletableFuture.allOf(task1, task2, task3);
// System.out.println(cf6.get(20, TimeUnit.MILLISECONDS));
    System.out.println("cf6.get()=" + cf6.get());
    /** * 區別: * 1:allof等待全部任務執行完成才執行cf6 * 2:anyOf是隻有一個任務執行完成,不管是正常執行或者執行異常,都會執行cf6 */
    // allof:若是有一個任務異常終止,則cf6.get時會拋出異常,都是正常執行,cf6.get返回null
    // anyOf:cf6.get的結果就是已執行完成的任務的執行結果
}
複製代碼

執行結果如圖:markdown

image.png 歡迎評論區指正和交流。app

相關文章
相關標籤/搜索