CompletableFuture常見用法射众,CompletableFuture使用示例碟摆,CompletableFuture等待所有異步任務(wù)返回

CompletableFuture常見用法,CompletableFuture使用示例责球,CompletableFuture等待所有異步任務(wù)返回焦履,包括常見的用法,結(jié)合自定義線程池使用雏逾。結(jié)合實(shí)際業(yè)務(wù)Demo代碼運(yùn)行效果如下嘉裤,可直接運(yùn)行查看效果,具體請(qǐng)參考如下代碼

1.創(chuàng)建CompletableFuture對(duì)象

方法名  功能描述
completedFuture(U value)    返回一個(gè)已經(jīng)計(jì)算好的CompletableFuture
runAsync(Runnable runnable) 使用ForkJoinPool.commonPool()作為線程池執(zhí)行任務(wù)栖博,沒有返回值
runAsync(Runnable runnable, Executor executor)  使用指定的線程池執(zhí)行任務(wù)屑宠,沒有返回值
supplyAsync(Supplier<U> supplier)   使用ForkJoinPool.commonPool()作為線程池執(zhí)行任務(wù),有返回值
supplyAsync(Supplier<U> supplier, Executor executor)    使用指定的線程池執(zhí)行任務(wù)仇让,有返回值

各種使用示例如下(可直接復(fù)制運(yùn)行):

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 1.創(chuàng)建CompletableFuture對(duì)象
        //  方法名  功能描述
        //  completedFuture(U value)    返回一個(gè)已經(jīng)計(jì)算好的CompletableFuture
        //  runAsync(Runnable runnable) 使用ForkJoinPool.commonPool()作為線程池執(zhí)行任務(wù)典奉,沒有返回值
        //  runAsync(Runnable runnable, Executor executor)  使用指定的線程池執(zhí)行任務(wù)躺翻,沒有返回值
        //  supplyAsync(Supplier<U> supplier)   使用ForkJoinPool.commonPool()作為線程池執(zhí)行任務(wù),有返回值
        //  supplyAsync(Supplier<U> supplier, Executor executor)    使用指定的線程池執(zhí)行任務(wù)卫玖,有返回值

        CompletableFuture<Integer> intFuture = CompletableFuture.completedFuture(100);
        // 100
        System.out.println(intFuture.get());

        CompletableFuture<Void> voidFuture = CompletableFuture.runAsync(() -> System.out.println("hello"));
        // null
        System.out.println(voidFuture.get());

        CompletableFuture<String> stringFuture = CompletableFuture.supplyAsync(() -> "hello");
        // hello
        System.out.println("stringFuture="+stringFuture.get());


        // 2.計(jì)算結(jié)果完成時(shí).可以執(zhí)行的方法
        // 方法名
        // whenComplete(BiConsumer<? super T,? super Throwable> action)
        // whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
        // whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)

        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            return "hello";
        }).whenComplete((v, e) -> {
            // hello
            System.out.println(v);
        });
        // hello
        System.out.println(future.get());

        // 3.轉(zhuǎn)換公你,消費(fèi),執(zhí)行
        // 方法名      功能描述
        // thenApply    獲取上一個(gè)任務(wù)的返回假瞬,并返回當(dāng)前任務(wù)的值
        // thenAccept   獲取上一個(gè)任務(wù)的返回陕靠,單純消費(fèi),沒有返回值
        // thenRun      上一個(gè)任務(wù)執(zhí)行完成后脱茉,開始執(zhí)行thenRun中的任務(wù)
        CompletableFuture.supplyAsync(() -> {
            return "hello ";
        }).thenAccept(str -> {
            // hello world
            System.out.println(str + "world");
        }).thenRun(() -> {
            // task finish
            System.out.println("task finish");
        });

        // 4.組合(兩個(gè)任務(wù)都完成)
        // 方法名  描述
        // thenCombine  組合兩個(gè)future剪芥,獲取兩個(gè)future的返回結(jié)果,并返回當(dāng)前任務(wù)的返回值
        // thenAcceptBoth   組合兩個(gè)future琴许,獲取兩個(gè)future任務(wù)的返回結(jié)果税肪,然后處理任務(wù),沒有返回值
        // runAfterBoth 組合兩個(gè)future榜田,不需要獲取future的結(jié)果益兄,只需兩個(gè)future處理完任務(wù)后,處理該任務(wù)
        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> {
            return "歡迎關(guān)注 ";
        }).thenApply(t -> {
            return t + "微信公眾號(hào) ";
        }).thenCombine(CompletableFuture.completedFuture("Java"), (t, u) -> {
            return t + u;
        }).whenComplete((t, e) -> {
            // 歡迎關(guān)注 微信公眾號(hào) Java
            System.out.println(t);
        });

        // 5.組合(只需要一個(gè)任務(wù)完成)
        // 方法名  描述
        // applyToEither    兩個(gè)任務(wù)有一個(gè)執(zhí)行完成串慰,獲取它的返回值偏塞,處理任務(wù)并返回當(dāng)前任務(wù)的返回值
        // acceptEither 兩個(gè)任務(wù)有一個(gè)執(zhí)行完成,獲取它的返回值邦鲫,處理任務(wù)灸叼,沒有返回值
        // runAfterEither   兩個(gè)任務(wù)有一個(gè)執(zhí)行完成,不需要獲取future的結(jié)果庆捺,處理任務(wù)古今,也沒有返回值
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            return "歡迎關(guān)注微信公眾號(hào)";
        });
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            return "Java";
        });
        CompletableFuture<String> future3 = future1.applyToEither(future2, str -> str);

        // 歡迎關(guān)注微信公眾號(hào) Java 隨機(jī)輸出
        System.out.println(future3.get());


        //  6.多任務(wù)組合
        //  方法名 描述
        //  allOf   當(dāng)所有的CompletableFuture完成后執(zhí)行計(jì)算
        //  anyOf   任意一個(gè)CompletableFuture完成后執(zhí)行計(jì)算
        //  allOf的使用
        CompletableFuture<String> future1A = CompletableFuture.supplyAsync(() -> {
            sleepRandom();
            return "歡迎關(guān)注";
        });
        CompletableFuture<String> future2A = CompletableFuture.supplyAsync(() -> {
            sleepRandom();
            return "微信公眾號(hào)";
        });
        CompletableFuture<String> future3A = CompletableFuture.supplyAsync(() -> {
            sleepRandom();
            return "Java識(shí)堂";
        });

        // 歡迎關(guān)注 微信公眾號(hào) Java
        CompletableFuture.allOf(future1A, future2A, future3A)
                .thenApply(v -> {
                            List<Object> collect = Stream.of(future1, future2, future3A)
                                    .map(CompletableFuture::join)
                                    .collect(Collectors.toList());
                            return collect;
                        }
                )
                .thenAccept(System.out::print);

        // anyOf的使用
        CompletableFuture<String> future1C = CompletableFuture.supplyAsync(() -> {
            sleepRandom();
            return "歡迎關(guān)注";
        });
        CompletableFuture<String> future2C = CompletableFuture.supplyAsync(() -> {
            sleepRandom();
            return "微信公眾號(hào)";
        });
        CompletableFuture<String> future3C = CompletableFuture.supplyAsync(() -> {
            sleepRandom();
            return "Java";
        });
        CompletableFuture<Object> resultFuture = CompletableFuture.anyOf(future1C, future2C, future3C);
        // 歡迎關(guān)注 微信公眾號(hào) Java 隨機(jī)輸出
        System.out.println(resultFuture.get());


        // 7.異常處理
        // exceptionally    捕獲異常嚷兔,進(jìn)行處理
        CompletableFuture<Integer> futureC = CompletableFuture.supplyAsync(() -> {
            return 100 / 0;
        }).thenApply(num -> {
            return num + 10;
        }).exceptionally(throwable -> {
            return 0;
        });
        // 0
        System.out.println(future.get());
        // 當(dāng)然有一些接口能捕獲異常

        CompletableFuture futureAAA = CompletableFuture.supplyAsync(() -> {
            String str = null;
            return str.length();
        }).whenComplete((v, e) -> {
            if (e == null) {
                System.out.println("正常結(jié)果為" + v);
            } else {
                // 發(fā)生異常了java.util.concurrent.CompletionException: java.lang.NullPointerException
                System.out.println("發(fā)生異常了" + e.toString());
            }
        });


        // 8.集合業(yè)務(wù)使用示例举瑰,假設(shè)stringList為業(yè)務(wù)執(zhí)行集合
        ExecutorService executor = new ThreadPoolExecutor(10, 16, 10, TimeUnit.MICROSECONDS, new ArrayBlockingQueue<>(1000));

        List<String> stringList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            stringList.add("a" + i);
        }

        CompletableFuture<Void> all = null;
        CompletableFuture<Void> all1 = null;
        // 開始我們的業(yè)務(wù)處理
        for (String personName : stringList) {
            CompletableFuture<Object> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
                return null;
            }).whenComplete((v, e) -> {
                if (e == null) {
                    System.out.println("正常結(jié)果為" + v);
                } else {
                    // 發(fā)生異常了java.util.concurrent.CompletionException: java.lang.NullPointerException
                    System.out.println("發(fā)生異常了" + e.toString());
                }
            });

            all = CompletableFuture.allOf(stringCompletableFuture);

            CompletableFuture<String> stringCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
                // 模擬業(yè)務(wù)邏輯,say hello world
                System.out.println(personName + ": Hello World!");
                return "task finished!";
            });
            all1 = CompletableFuture.allOf(stringCompletableFuture1);
        }

        // 開始等待所有任務(wù)執(zhí)行完成
        all.join();
        all1.join();

        // 使用JDK 1.8的特性何陆,stream()和Lambda表達(dá)式: (參數(shù)) -> {表達(dá)式}
        long start = System.currentTimeMillis();

        if (CollectionUtils.isEmpty(stringList)) {
            return;
        }
        final CompletableFuture[] completableFutures = stringList.stream().
                map(t -> CompletableFuture
                        .supplyAsync(() -> pause(t), executor)
                        .whenComplete((result, th) -> {
                            System.out.println("hello" + result);
                        })).toArray(CompletableFuture[]::new);

        // 開始等待所有任務(wù)執(zhí)行完成
        System.out.println("start block");
        CompletableFuture.allOf(completableFutures).join();
        System.out.println("block finish, consume time:" + (System.currentTimeMillis() - start));

        stringList.forEach(name -> CompletableFuture.supplyAsync(() -> {
            // 封裝了業(yè)務(wù)邏輯
            System.out.println("name = " + name);
            return "success";
        }).exceptionally(e -> {
            System.out.println(e);
            return "false";
        }));

        // 關(guān)閉線程池
        executor.shutdown();
    }

    private static void sleepRandom() {
        System.out.println("測(cè)試方法");
    }

    public static String pause(String name) {
        try {
            Thread.sleep(300);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return name;
    }
}

簡(jiǎn)約寫法CompletableFuture執(zhí)行任務(wù)并返回


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @author lisanwei24282
 */
public class CompletableFutureProblem {
    public void batchOperation() {
        /* 集合任務(wù)你画,統(tǒng)一處理 */
        List<String> stringList = new ArrayList<>();
        stringList.add("task1");
        stringList.add("task2");

        /* 任務(wù)提交匯總 */
        List<CompletableFuture<String>> futures = new ArrayList<>();
        stringList.parallelStream().forEach(str -> {
            /* 調(diào)用業(yè)務(wù)方法 */
            CompletableFuture<String> response = restApiCall(str);
            futures.add(response);
        });

        /* 等待所有返回 */
        CompletableFuture<Void> result = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
        CompletableFuture<List<String>> convertedResult = result.thenApply(v ->
                futures.stream().map(CompletableFuture::join).collect(Collectors.toList())
        );

        /* 獲取返回?cái)?shù)據(jù)結(jié)果 */
        try {
            List<String> finishedTask = convertedResult.get();
            System.out.println(finishedTask.toString());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

    /* 假設(shè)執(zhí)行具體業(yè)務(wù)邏輯功能 */
    public CompletableFuture<String> restApiCall(String str) {
        return CompletableFuture.supplyAsync(() -> {
            return "Complete-" + str;
        });
    }

    public static void main(String[] args) {
        CompletableFutureProblem problem = new CompletableFutureProblem();
        problem.batchOperation();
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末抵碟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坏匪,更是在濱河造成了極大的恐慌拟逮,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件适滓,死亡現(xiàn)場(chǎng)離奇詭異敦迄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門罚屋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)苦囱,“玉大人,你說我怎么就攤上這事脾猛∷和” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵猛拴,是天一觀的道長(zhǎng)喉刘。 經(jīng)常有香客問我,道長(zhǎng)漆弄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任造锅,我火速辦了婚禮撼唾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哥蔚。我一直安慰自己倒谷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布糙箍。 她就那樣靜靜地躺著渤愁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪深夯。 梳的紋絲不亂的頭發(fā)上抖格,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音咕晋,去河邊找鬼雹拄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛掌呜,可吹牛的內(nèi)容都是我干的滓玖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼质蕉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼势篡!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起模暗,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤禁悠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后汰蓉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绷蹲,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了祝钢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片比规。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拦英,靈堂內(nèi)的尸體忽然破棺而出蜒什,到底是詐尸還是另有隱情,我是刑警寧澤疤估,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布灾常,位于F島的核電站,受9級(jí)特大地震影響铃拇,放射性物質(zhì)發(fā)生泄漏钞瀑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一慷荔、第九天 我趴在偏房一處隱蔽的房頂上張望雕什。 院中可真熱鬧,春花似錦显晶、人聲如沸贷岸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)偿警。三九已至,卻和暖如春唯笙,著一層夾襖步出監(jiān)牢的瞬間螟蒸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工崩掘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尿庐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓呢堰,卻偏偏與公主長(zhǎng)得像抄瑟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枉疼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容