CompletableFuture測試用例

package future;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author XRZ
 * @date 2020/6/15 18:05
 * @Description :
 */
public class FutureTest {

    private ThreadPoolExecutor executor;

    @Before
    public void init(){
        executor = new ThreadPoolExecutor(
                2,
                4,
                30,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>()
        );
    }

    @After
    public void waitAsync() throws InterruptedException {
        Thread.sleep(5000);
    }


    @Test
    public void cretae_CompletableFuture() throws Exception {
        /**
         * CompletableFuture.runAsync(Runnable runnable);
         */
        CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"======>無返回值異步線程,使用JDK默認線程池執行:ForkJoinPool.commonPool()");
        });

        /**
         * CompletableFuture.runAsync(Runnable runnable, Executor executor);
         */
        CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"======>無返回值異步線程,使用指定線程池執行");
        },executor);

        /**
         * CompletableFuture.supplyAsync(Supplier<U> supplier);
         */
        CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {
            return Thread.currentThread().getName()+"======>有返回值異步線程,使用JDK默認線程池執行:ForkJoinPool.commonPool()";
        });
        System.out.println(completableFuture1.get());

        /**
         * CompletableFuture.supplyAsync(Supplier<U> supplier, Executor executor)
         */
        CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
            return Thread.currentThread().getName() + "======>有返回值異步線程,使用指定線程池執行";
        }, executor);
        System.out.println(completableFuture2.get());

//        ForkJoinPool.commonPool-worker-1======>無返回值異步線程,使用JDK默認線程池執行:ForkJoinPool.commonPool()
//        pool-1-thread-1======>無返回值異步線程,使用指定線程池執行
//        ForkJoinPool.commonPool-worker-1======>有返回值異步線程,使用JDK默認線程池執行:ForkJoinPool.commonPool()
//        pool-1-thread-2======>有返回值異步線程,使用指定線程池執行
    }

    @Test
    public void get_CompletableFuture() throws Exception {
        /**
         *  CompletableFuture.get() 獲取結果
         */
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "result");
        System.out.println(future1.get());
        /**
         *  CompletableFuture.getNow(T valueIfAbsent) 獲取結果,如果在執行getNow的時候,還未返回結果或者拋了異常,返回valueIfAbsent
         */
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "result");
        Thread.sleep(500);
        System.out.println(future2.getNow("res"));
        /**
         *  CompletableFuture.get(long timeout, TimeUnit unit) 獲取結果,如果超過等待時間,throw TimeoutException
         */
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "result";
        });
        System.out.println(future3.get(1,TimeUnit.SECONDS));

//        result
//        result
//
//        java.util.concurrent.TimeoutException
    }

    @Test
    public void complete_CompletableFuture() throws Exception {
        /**
         * complete(T t) :結束異步線程,返回T(多次調用以第一次爲準)
         */
        CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> "RESULT");
        completableFuture1.complete("結束異步線程,返回指定結果");
        System.out.println(completableFuture1.get());

        /**
         * completeExceptionally(Throwable ex) :結束異步線程,返回一個異常
         */
        CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> "RESULT");
        // Thread.sleep(1000);
        completableFuture2.completeExceptionally(new RuntimeException("結束異步線程,返回自定義異常"));
        System.out.println(completableFuture2.get());

        /**
         *  如果異步線程比主線程先執行完成,則正常返回,complete/completeExceptionally 失效
         */

//        結束異步線程,返回指定結果
//
//        java.util.concurrent.ExecutionException: java.lang.RuntimeException: 結束異步線程,返回自定義異常
    }


    @Test
    public void thenApply_CompletableFuture() throws Exception{
        /**
         *  結果轉換  T -> U
         *  thenApply(Function<? super T,? extends U> fn)
         *  thenApplyAsync(Function<? super T,? extends U> fn)
         *  thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
         */
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> "RESULT")
                .thenApply(res -> res + "Convert")
                .thenApply(String::length);
        System.out.println(future.get());

//        13
    }


    @Test
    public void whenComplete_CompletableFuture() throws Exception{
        /**
         *  對結果的處理
         *  whenComplete(BiConsumer<? super T,? super Throwable> action)
         *  whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
         *  whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
         */
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 1/0)
                .whenComplete((res, e) -> {
                    System.out.println("RESULT:"+res);
                    System.out.println("異常信息:"+e);
                });
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 1/1)
                .whenComplete((res, e) -> {
                    System.out.println("RESULT:"+res);
                    System.out.println("異常信息:"+e);
                });
        System.out.println(future2.get());

//        RESULT:null
//        異常信息:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
//        RESULT:1
//        異常信息:null
//        1
    }


    @Test
    public void handle_CompletableFuture() throws Exception{
        /**
         * 對結果的處理並且轉換
         * handle(BiFunction<? super T, Throwable, ? extends U> fn)
         * handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
         * handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
         */
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> 1/1)
                .handle((res, e) -> {
                    System.out.println("RESULT:"+res);
                    System.out.println("異常信息:"+e);
                    return "RESULT";
                });
        System.out.println(future2.get());

//        RESULT:1
//        異常信息:null
//        RESULT
    }


    @Test
    public void thenAccept_CompletableFuture() throws Exception{
        /**
         *  thenAccept(Consumer<? super T> action)
         *  thenAcceptAsync(Consumer<? super T> action)
         *  thenAcceptAsync(Consumer<? super T> action, Executor executor)
         */
        CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> "RESULT")
                .thenAccept(res -> {
                    System.out.println("消費結果且無返回:"+res);
                });
        System.out.println(future.get()); //null

//        消費結果且無返回:RESULT
//        null
    }


    @Test
    public void thenRun_CompletableFuture() throws Exception{
        /**
         *  thenRun(Runnable action)
         *  thenRunAsync(Runnable action)
         *  thenRunAsync(Runnable action, Executor executor)
         */
        CompletableFuture.runAsync(() -> {
            System.out.println("異步線程方法執行1");
        }).thenRun(() -> {
            System.out.println("異步線程方法執行2");
        }).thenRun(() -> {
            System.out.println("異步線程方法執行3");
        });

//        異步線程方法執行1
//        異步線程方法執行2
//        異步線程方法執行3
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章