jdk8中CompletableFuture的各個API用法

https://www.cnblogs.com/houzheng/p/10964314.html

 

package cn.hou.completablefuture;

import org.junit.Test;

import java.util.concurrent.*;

public class CompletableFutureDemo {

    /**
     * 在Java8中,CompletableFuture提供了非常強大的Future的擴展功能,可以幫助我們簡化異步編程的複雜性,
     * 並且提供了函數式編程的能力,可以通過回調的方式處理計算結果,也提供了轉換和組合 CompletableFuture 的方法
     *
     *  注意: 方法中有Async一般表示另起一個線程,沒有表示用當前線程
     */
    @Test
    public void test01() throws Exception {

        ExecutorService service = Executors.newFixedThreadPool(5);
        /**
         *  supplyAsync用於有返回值的任務,
         *  runAsync則用於沒有返回值的任務
         *  Executor參數可以手動指定線程池,否則默認ForkJoinPool.commonPool()系統級公共線程池
         */
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "侯徵";
        }, service);

        CompletableFuture<Void> data = CompletableFuture.runAsync(() -> System.out.println("侯徵"));

        /**
         * 計算結果完成回調
         */
        future.whenComplete((x,y)-> System.out.println(x+","+y)); //執行當前任務的線程執行繼續執
        data.whenCompleteAsync((x,y)-> System.out.println(x+","+y)); // 交給線程池另起線程執行
        future.exceptionally(Throwable::toString);
        //System.out.println(future.get());


        /**
         * thenApply,一個線程依賴另一個線程可以使用,出現異常不執行
         */
        //第二個線程依賴第一個的結果
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 5).thenApply(x -> x);


        /**
         * handle 是執行任務完成時對結果的處理,第一個出現異常繼續執行
         */
        CompletableFuture<Integer> future2 = future1.handleAsync((x, y) -> x + 2);
        System.out.println(future2.get());//7


        /**
         * thenAccept 消費處理結果,不返回
         */
        future2.thenAccept(System.out::println);


        /**
         * thenRun  不關心任務的處理結果。只要上面的任務執行完成,就開始執行
         */
        future2.thenRunAsync(()-> System.out.println("繼續下一個任務"));


        /**
         * thenCombine 會把 兩個 CompletionStage 的任務都執行完成後,兩個任務的結果交給 thenCombine 來處理
         */
        CompletableFuture<Integer> future3 = future1.thenCombine(future2, Integer::sum);
        System.out.println(future3.get()); // 5+7=12


        /**
         * thenAcceptBoth : 當兩個CompletionStage都執行完成後,把結果一塊交給thenAcceptBoth來進行消耗
         */
        future1.thenAcceptBothAsync(future2,(x,y)-> System.out.println(x+","+y)); //5,7


        /**
         * applyToEither
         * 兩個CompletionStage,誰執行返回的結果快,我就用那個CompletionStage的結果進行下一步的轉化操作
         */
        CompletableFuture<Integer> future4 = future1.applyToEither(future2, x -> x);
        System.out.println(future4.get()); //5


        /**
         * acceptEither
         * 兩個CompletionStage,誰執行返回的結果快,我就用那個CompletionStage的結果進行下一步的消耗操作
         */
        future1.acceptEither(future2, System.out::println);


        /**
         * runAfterEither
         * 兩個CompletionStage,任何一個完成了都會執行下一步的操作(Runnable
         */
        future1.runAfterEither(future,()-> System.out.println("有一個完成了,我繼續"));


        /**
         * runAfterBoth
         * 兩個CompletionStage,都完成了計算纔會執行下一步的操作(Runnable)
         */
        future1.runAfterBoth(future,()-> System.out.println("都完成了,我繼續"));


        /**
         * thenCompose 方法
         * thenCompose 方法允許你對多個 CompletionStage 進行流水線操作,第一個操作完成時,將其結果作爲參數傳遞給第二個操作
         * thenApply是接受一個函數,thenCompose是接受一個future實例,更適合處理流操作
         */
        future1.thenComposeAsync(x->CompletableFuture.supplyAsync(()->x+1))
                .thenComposeAsync(x->CompletableFuture.supplyAsync(()->x+2))
                .thenCompose(x->CompletableFuture.runAsync(()-> System.out.println("流操作結果:"+x)));
        TimeUnit.SECONDS.sleep(5);//主線程sleep,等待其他線程執行
    }
}

 

發佈了22 篇原創文章 · 獲贊 15 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章