并发编程-CompletableFuture全方法详解

CompletableFuture

以下是学习中的一些笔记记录,如果有错误希望得到你的指正~ 同时也希望对你有点帮助~

CompletableFuture 实现了CompletionStageFutureCompletionStage表示异步任务中的某一个阶段或某一个操作,其返回值是一个新的阶段CompletionStageCompletableFuture就表示一个Future完成后要做的操作。通过Future同步等待执行结果,通过CompletionStage增强异步回调的功能。

CompletionStage 异步任务分类

  • 纯消费类型方法

    纯消费类型的方法指依赖上一个异步任务的结果作为当前CompletionStage 的参数进行下一步计算,它的特点是不返回新的计算值,这类的方法都包含Accept关键字。在CompletionStage 中包含9个方法,这9个方法又可以分为三类:

    ​ 1、依赖单个CompletionStage 任务完成

    ​ 2、依赖两个CompletionStage 任务都完成

    ​ 3、依赖两个CompletionStage 中的任何一个完成

    //此阶段正常完成时,将使用此阶段的结果作为提供的操作的参数来执行该阶段。同步执行该阶段
    public CompletionStage<Void> thenAccept(Consumer<? super T> action);
    
    //此阶段正常完成时,将使用此阶段的默认异步执行工具(ForkJoinPool)执行该阶段,并将此阶段的结果作为提供的操作的参数。
    public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
    
    //当该阶段正常完成时,将使用提供的执行器执行该阶段,该阶段的结果作为提供的操作的参数。
    public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action,
                                                 Executor executor);
    
    //当此阶段和另一个给定阶段都正常完成时,该阶段将以两个结果作为提供的操作的参数执行。
    public <U> CompletionStage<Void> thenAcceptBoth(CompletionStage<? extends U> other,
                                                 BiConsumer<? super T, ? super U> action);
    
    //当此阶段和另一个给定阶段正常完成时,将使用此阶段的默认异步执行工具执行该阶段,并将两个结果作为提供的操作的参数。
    public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,
                                                         BiConsumer<? super T, ? super U> action);
    
    //当此阶段和另一个给定阶段正常完成时,使用该阶段提供的执行器执行,两个结果作为提供的函数的参数。
    public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,
                                                         BiConsumer<? super T, ? super U> action,
                                                         Executor executor);
    
    //当此阶段或其他给定阶段正常完成时,该阶段将以相应的结果作为提供的操作的参数执行。
    public CompletionStage<Void> acceptEither(CompletionStage<? extends T> other,
                                              Consumer<? super T> action);
    
    //当此阶段或其他给定阶段正常完成时,将使用此阶段的默认异步执行工具执行该阶段,并将相应的结果作为提供的操作的参数。
    public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other, 
                                                   Consumer<? super T> action);
    
    //当此阶段或其他给定阶段正常完成时,使用该阶段提供的执行器执行,相应的结果作为提供的函数的参数。
    public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other,
                                                   Consumer<? super T> action, 
                                                   Executor executor);
    
/**
 * CompletableFuture 消费类型方法 指依赖上一个异步任务的结果作为当前 `CompletionStage`的参数进行下一步计算,没有返回值,一个CompletableFuture就是一个Stage
 *
 * @author zdp
 * @date 2022-07-14 10:04
 */
public class ConsumeNoReturnMethodExample {

    public static volatile int var = 5;

    public static void main(String[] args) {
        //thenAccept(Consumer<? super T> action) 同步执行
        CompletableFuture.supplyAsync(() -> var).thenAccept(integer -> {
            integer += 5;
            System.out.println("thenAccept 执行结果 => " + integer);
        });
        System.out.println("main 线程执行到了..thenAccept");
        System.out.println("thenAcceptAsync--------------------------------------");

        //thenAcceptAsync(Consumer<? super T> action) 异步执行,由默认的 ForkJoinPool.commonPool()线程池执行
        CompletableFuture.supplyAsync(() -> var).thenAcceptAsync(integer -> {
            integer += 5;
            System.out.println("thenAcceptAsync 执行结果 => " + integer);
        });
        System.out.println("main 线程执行到了..thenAcceptAsync");
        System.out.println("thenAcceptAsync--------------------------------------");

        //thenAcceptAsync(Consumer<? super T> action, Executor executor) 异步执行,由指定的线程池执行
        CompletableFuture.supplyAsync(() -> var).thenAcceptAsync(integer -> {
            integer += 5;
            System.out.println("thenAcceptAsync Executors 执行结果 => " + integer);
        }, Executors.newFixedThreadPool(10));
        System.out.println("main 线程执行到了..thenAcceptAsync Executors");

        System.out.println("thenAcceptBoth--------------------------------------");
        //thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action) 异步执行,将两阶段的结果参数交给BiConsumer来执行
        CompletableFuture.supplyAsync(() -> var).thenAcceptBoth(CompletableFuture.supplyAsync(() -> {
            sleep();
            return 10;
        }), (r1, r2) -> System.out.println("thenAcceptBoth 执行结果 => " + (r1 + r2)));
        System.out.println("main 线程执行到了..thenAcceptBoth");

        System.out.println("thenAcceptBothAsync--------------------------------------");
        //public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)
        //由默认的 ForkJoinPool.commonPool()线程池异步执行,将两个Stage任务的返回结果作为参数,给到BiConsumer进行操作
        CompletableFuture.supplyAsync(() -> var).thenAcceptBothAsync(CompletableFuture.supplyAsync(ConsumeNoReturnMethodExample::sleep),
                (r1, r2) -> System.out.println("thenAcceptBothAsync 执行结果 => " + (r1 + r2)));
        System.out.println("main 线程执行到了..thenAcceptBothAsync");

        System.out.println("thenAcceptBothAsync--------------------------------------");
        //public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor)
        //由给定的 Executors 线程池异步执行,将两个Stage任务的返回结果作为参数,给到BiConsumer进行操作
        CompletableFuture.supplyAsync(() -> var).thenAcceptBothAsync(CompletableFuture.supplyAsync(ConsumeNoReturnMethodExample::sleep),
                (r1, r2) -> System.out.println("thenAcceptBothAsync Executors 执行结果 => " + (r1 + r2)), Executors.newFixedThreadPool(10));
        System.out.println("main 线程执行到了..thenAcceptBothAsync Executors");

        System.out.println("acceptEither--------------------------------------");
        //public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action) 异步执行,当有Stage任务执行完就开始执行
        CompletableFuture.supplyAsync(ConsumeNoReturnMethodExample::sleep).acceptEither(CompletableFuture.supplyAsync(() -> var),
                result -> System.out.println("acceptEither 执行结果 => " + result));
        System.out.println("main 线程执行到了..acceptEither");

        System.out.println("acceptEitherAsync--------------------------------------");
        //public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action) 由默认的 ForkJoinPool.commonPool()线程池异步执行,当有Stage任务执行完就开始执行
        CompletableFuture.supplyAsync(ConsumeNoReturnMethodExample::sleep).acceptEitherAsync(CompletableFuture.supplyAsync(() -> var),
                result -> System.out.println("acceptEitherAsync 执行结果 => " + result));
        System.out.println("main 线程执行到了..acceptEitherAsync");

        System.out.println("acceptEitherAsync Executors--------------------------------------");
        //public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action) 由默认的 ForkJoinPool.commonPool()线程池异步执行,当有Stage任务执行完就开始执行
        CompletableFuture.supplyAsync(ConsumeNoReturnMethodExample::sleep).acceptEitherAsync(CompletableFuture.supplyAsync(() -> var),
                result -> System.out.println("acceptEitherAsync Executors执行结果 => " + result), Executors.newFixedThreadPool(10));
        System.out.println("main 线程执行到了..acceptEitherAsync Executors");
    }


    public static int sleep(){
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 10;
    }
}
  • 有返回值类型的方法

    有返回值类型的方法就是用上一个异步任务的执行结果进行下一步计算,并且会产生一个新的有返回值的CompletionStage对象,在CompletionStage中定义了9个带有返回结果的方法,这9个方法也可分为3类:

    ​ 1、依赖单个CompletionStage任务完成

    ​ 2、依赖两个CompletionStage任务完成

    ​ 3、依赖两个CompletionStage中的任何一个完成

    //当上阶段正常完成时,当前阶段将以上阶段的结果作为参数执行,返回该阶段的执行结果
    public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
    
    //当上阶段正常完成时,将使用该阶段的默认异步执行工具执行该阶段,并将上阶段的结果作为函数的参数,返回该阶段的执行结果
    public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
    
    //当上阶段正常完成时,将使用该阶段的提供的异步执行工具执行该阶段,并将上阶段的结果作为函数的参数,返回该阶段的执行结果
    public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor);
    
    //由调用线程执行,当给定的两个阶段都执行完成时,该阶段将两个给定阶段的任务执行结果作为参数执行,并返回该阶段的执行结果
    public <U,V> CompletionStage<V> thenCombine (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
    
    //由默认的线程池执行,当给定的两个阶段都执行完成时,该阶段将两个给定阶段的任务执行结果作为参数执行,并返回该阶段的执行结果
    public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
    
    //由给定的线程池执行,当给定的两个阶段都执行完成时,该阶段将两个给定阶段的任务执行结果作为参数执行,并返回该阶段的执行结果
    public <U,V> CompletionStage<V> thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);
    
    //由调用线程执行,当这个或另一个给定的阶段正常完成时,该阶段将以相应的结果作为提供的函数的参数执行,并返回该阶段的任务执行结果
    public <U> CompletionStage<U> applyToEither (CompletionStage<? extends T> other, Function<? super T, U> fn);
    
    //由默认的线程池执行,当这个或另一个给定的阶段正常完成时,该阶段将以相应的结果作为提供的函数的参数执行,并返回该阶段的任务执行结果
    public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn);
    
    //由给定的线程池执行,当这个或另一个给定的阶段正常完成时,该阶段将以相应的结果作为提供的函数的参数执行,并返回该阶段的任务执行结果
    public <U> CompletionStage<U> applyToEitherAsync (CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
    
  • 不消费也不返回的方法

    //当上阶段正常完成时,该阶段将执行指定的操作,不消费上一阶段的参数,也不返回新的任务执行结果
    public CompletionStage<Void> thenRun(Runnable action);
    
    //当上一个阶段runAsync执行完成时(该阶段由默认线程池执行),thenRunAsync()这个阶段执行指定的操作,不消费也不返回结果
    public CompletionStage<Void> thenRunAsync(Runnable action);
    
    //当上一个阶段runAsync执行完成时(该阶段由默认线程池执行),thenRunAsync()这个阶段执行指定的操作(thenRunAsync这个阶段由自定义的线程池执行),不消费也不返回结果
    public CompletionStage<Void> thenRunAsync(Runnable action, Executor executor);
    
    //当给定的两个阶段都正常完成时,然后该阶段执行指定的操作
    public CompletionStage<Void> runAfterBoth(CompletionStage<?> other,
                                              Runnable action);
    
    //当给定的两个阶段完成时,用默认的异步执行工具来执行
    public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other,
                                                   Runnable action);
    
    //当给定的两个阶段完成时,用指定的线程池来执行
    public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other,
                                                   Runnable action,
                                                   Executor executor);
    
    //当给定的两个阶段中有任一阶段完成,由调用线程来执行该阶段的操作
    public CompletionStage<Void> runAfterEither(CompletionStage<?> other,
                                                Runnable action);
    
    //当给定的两个阶段中有任一阶段完成,使用默认的线程池来执行该阶段的操作
    public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other,
                                                     Runnable action);
    
    //当给定的两个阶段中有任一阶段完成,用指定的线程池来执行
    public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other,
                                                     Runnable action,
                                                     Executor executor);
    
/**
 * 有返回值类型的方法 依赖上一个阶段的任务执行结果来对当前Stage进行计算
 *
 * @author zdp
 * @date 2022-07-21 14:21
 */
public class CompletableHasReturnMethodExample {

    public static ThreadPoolTaskExecutor executors = getExecutor();

    public static volatile int var = 5;

    public static void main(String[] args) throws Exception{

        //由调用线程来执行该方法这里就是main线程,消费上一个阶段的任务执行结果,返回一个计算结果
        CompletableFuture<String> thenApply = CompletableFuture.supplyAsync(() -> var).thenApply(str ->  {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "线程【" + Thread.currentThread().getName() + "】thenApply计算结果 => " + str;
        });
        System.out.println("thenApply 任务执行结果 => " + thenApply.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了thenApply....");

        System.out.println("thenApplyAsync==================================");
        //由默认的ForkJoinPool.commonPool()来执行,消费上一个阶段的任务执行结果,返回一个计算结果
        CompletableFuture<String> thenApplyAsync = CompletableFuture.supplyAsync(() -> var).thenApplyAsync(str ->  {
            System.out.println();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "线程【" + Thread.currentThread().getName() + "】thenApplyAsync计算结果 => " + str;
        });
        System.out.println("thenApplyAsync 任务执行结果 => " + thenApplyAsync.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了thenApplyAsync....");

        System.out.println("thenApplyAsync Executors==================================");
        //由自定义的Executors来执行,消费上一个阶段的任务执行结果,返回一个计算结果
        CompletableFuture<String> thenApplyAsyncExecutor = CompletableFuture.supplyAsync(() -> var).thenApplyAsync(str ->  {
            System.out.println();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "线程【" + Thread.currentThread().getName() + "】thenApplyAsyncExecutor计算结果 => " + str;
        }, executors);
        System.out.println("thenApplyAsyncExecutor 任务执行结果 => " + thenApplyAsyncExecutor.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了thenApplyAsyncExecutor....");

        System.out.println("thenCombine==================================");
        //由调用线程执行,当给定的两个阶段都执行完成时,该阶段将两个给定阶段的任务执行结果作为参数执行,并返回该阶段的执行结果
        CompletableFuture<String> thenCombine = CompletableFuture.supplyAsync(() -> var).thenCombine(CompletableFuture.supplyAsync(() -> var),
                (r1, r2) -> "线程【" + Thread.currentThread().getName() + "】thenCombine => r1 = " + r1 + " , r2 = " +r2);
        System.out.println("thenCombine 任务执行结果 => " + thenCombine.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了thenCombine....");

        System.out.println("thenCombineAsync==================================");
        //由默认的线程池执行,当给定的两个阶段都执行完成时,该阶段将两个给定阶段的任务执行结果作为参数执行,并返回该阶段的执行结果
        CompletableFuture<String> thenCombineAsync = CompletableFuture.supplyAsync(() -> var).thenCombineAsync(CompletableFuture.supplyAsync(() -> var),
                (r1, r2) -> "线程【" + Thread.currentThread().getName() + "】thenCombineAsync => r1 = " + r1 + " , r2 = " +r2);
        System.out.println("thenCombineAsync 任务执行结果 => " + thenCombineAsync.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了thenCombineAsync....");

        System.out.println("thenCombineAsync Executors==================================");
        //由给定的线程池执行,当给定的两个阶段都执行完成时,该阶段将两个给定阶段的任务执行结果作为参数执行,并返回该阶段的执行结果
        CompletableFuture<String> thenCombineAsyncExecutors = CompletableFuture.supplyAsync(() -> var).thenCombineAsync(CompletableFuture.supplyAsync(() -> var),
                (r1, r2) -> "线程【" + Thread.currentThread().getName() + "】thenCombineAsyncExecutors => r1 = " + r1 + " , r2 = " +r2, executors);
        System.out.println("thenCombineAsyncExecutors 任务执行结果 => " + thenCombineAsyncExecutors.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了thenCombineAsyncExecutors....");

        System.out.println("applyToEither==================================");
        //由调用线程执行,当给定的两个阶段中有任意阶段完成,将完成任务阶段的执行结果作为该阶段的参数执行,并返回该阶段的执行结果
        CompletableFuture<String> applyToEither = CompletableFuture.supplyAsync(() -> var).applyToEither(CompletableFuture.supplyAsync(() -> 10),
                result -> "线程【" + Thread.currentThread().getName() + "】thenCombineAsyncExecutors => result = " + result);
        System.out.println("applyToEither 任务执行结果 => " + applyToEither.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了applyToEither....");

        System.out.println("applyToEitherAsync==================================");
        //由默认的线程池执行,当给定的两个阶段中有任意阶段完成,将完成任务阶段的执行结果作为该阶段的参数执行,并返回该阶段的执行结果
        CompletableFuture<String> applyToEitherAsync = CompletableFuture.supplyAsync(() -> 10).applyToEitherAsync(CompletableFuture.supplyAsync(() -> var),
                result -> "线程【" + Thread.currentThread().getName() + "】applyToEitherAsync => result = " + result);
        System.out.println("applyToEitherAsync 任务执行结果 => " + applyToEitherAsync.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了applyToEitherAsync....");

        System.out.println("applyToEitherAsyncExecutors==================================");
        //由给定的线程池执行,当给定的两个阶段中有任意阶段完成,将完成任务阶段的执行结果作为该阶段的参数执行,并返回该阶段的执行结果
        CompletableFuture<String> applyToEitherAsyncExecutors = CompletableFuture.supplyAsync(() -> var).applyToEitherAsync(CompletableFuture.supplyAsync(() -> 10),
                result -> "线程【" + Thread.currentThread().getName() + "】applyToEitherAsyncExecutors => result = " + result, executors);
        System.out.println("applyToEitherAsyncExecutors 任务执行结果 => " + applyToEitherAsyncExecutors.get());
        System.out.println("【" + Thread.currentThread().getName() + "】线程执行到了applyToEitherAsyncExecutors....");
    }


    public static ThreadPoolTaskExecutor getExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(24);
        executor.setMaxPoolSize(50);
        executor.setKeepAliveSeconds(60);
        executor.setQueueCapacity(200);
        executor.setAllowCoreThreadTimeOut(true);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}
  • 多个任务组合

    //由调用线程来执行thenCompose的操作,当上一个阶段执行完成的时候,用上一个阶段的任务执行结果作为该阶段的任务执行参数,并返回该阶段执行的任务执行结果
    public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends 													  CompletionStage<U>> fn);
    
    //由默认线程池来执行thenCompose的操作,当上一个阶段执行完成的时候,用上一个阶段的任务执行结果作为该阶段的任务执行参数,并返回该阶段执行的任务执行结果
    public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);
    
    //由指定线程池来执行thenCompose的操作,当上一个阶段执行完成的时候,用上一个阶段的任务执行结果作为该阶段的任务执行参数,并返回该阶段执行的任务执行结果
    public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);
    
/**
 * CompletableFuture 任务组合的方法
 *
 * @author zdp
 * @date 2022-07-25 17:32
 */
public class CompletableComposeExample {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //由调用线程来执行thenCompose的操作,当上一个阶段执行完成的时候,用上一个阶段的任务执行结果作为该阶段的任务执行参数,并返回该阶段执行的任务执行结果
        CompletableFuture<String> thenCompose = CompletableFuture.supplyAsync(() -> "resultOne").thenCompose( preResult -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenCompose....");
            return CompletableFuture.supplyAsync(() -> preResult + " resultTwo");
        });
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了thenComposeAsync....结果是: {" + thenCompose.get() + "}");
        System.out.println("================================================================");

        //由默认线程池来执行thenCompose的操作,当上一个阶段执行完成的时候,用上一个阶段的任务执行结果作为该阶段的任务执行参数,并返回该阶段执行的任务执行结果
        CompletableFuture<String> thenComposeAsync = CompletableFuture.supplyAsync(() -> "resultOne").thenComposeAsync( preResult -> {
            System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenComposeAsync....");
            return CompletableFuture.supplyAsync(() -> preResult + " resultTwo");
        });
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了thenComposeAsync....结果是: {" + thenComposeAsync.get() + "}");
        System.out.println("================================================================");

        //由指定线程池来执行thenCompose的操作,当上一个阶段执行完成的时候,用上一个阶段的任务执行结果作为该阶段的任务执行参数,并返回该阶段执行的任务执行结果
        CompletableFuture<String> thenComposeAsyncExecutor = CompletableFuture.supplyAsync(() -> "resultOne").thenComposeAsync( preResult -> {
            System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenComposeAsyncExecutor....");
            return CompletableFuture.supplyAsync(() -> preResult + " resultTwo");
        }, Executors.newFixedThreadPool(2));
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了thenComposeAsyncExecutor....结果是: {" + thenComposeAsyncExecutor.get() + "}");
        System.out.println("================================================================");
    }

}
  • 异常处理

    • whenComplete

      whenComplete表示当任务执行完成后会触发的方法,它的特点是不论前置的CompletionStage任务是正常执行结束还是出现异常,都能够触发特定的action方法

    //由调用线程执行whenComplete,当前面的阶段异常时,whenComplete阶段会返回异常信息,并且会中断程序不会继续往下执行,当前面的阶段正常执行,whenComplete阶段会正常返回结果
    public CompletionStage<T> whenComplete(BiConsumer<? super T, ? super Throwable> action);
    
    //由默认线程池执行whenCompleteAsync,当前面的阶段异常时,whenCompleteAsync阶段会返回异常信息,并且会中断程序不会继续往下执行,当前面的阶段正常执行,whenCompleteAsync阶段会正常返回结果
    public CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action);
    
    //由指定的线程池执行whenCompleteAsync,当前面的阶段异常时,whenCompleteAsync阶段会返回异常信息,并且会中断程序不会继续往下执行,当前面的阶段正常执行,whenCompleteAsync阶段会正常返回结果
    public CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,Executor executor);
    
    • handle

      handle 表示前置任务执行完成后,不管前置任务执行状态是正常还是异常,都会执行handle中的fn函数,它和whenComplete的作用几乎一致,不同点在于:handle是一个有返回值类型的方法

    //由调用线程执行handle,当前面的阶段异常时,handle阶段会返回异常信息,并且会忽略异常继续往下执行,当前面的阶段正常执行,handle阶段会返回handle阶段执行的结果,handle中的任务执行参数是上一个阶段执行的结果
    public <U> CompletionStage<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);
    
    //由默认线程池执行handle,当前面的阶段异常时,handle阶段会返回异常信息,并且会忽略异常继续往下执行,当前面的阶段正常执行,handle阶段会返回handle阶段执行的结果,handle中的任务执行参数是上一个阶段执行的结果
    public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);
    
    //由指定线程池执行handle,当前面的阶段异常时,handle阶段会返回异常信息,并且会忽略异常继续往下执行,当前面的阶段正常执行,handle阶段会返回handle阶段执行的结果,handle中的任务执行参数是上一个阶段执行的结果
    public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);
    
    • exceptionally

      exceptionally 接受一个fn函数,当上一个CompletionStage出现异常时,会把该异常作为参数传递到fn函数,正常执行就返回上阶段任务执行结果,异常就返回该阶段异常处理结果

    //由调用线程来执行exceptionally,当前面的阶段正常执行时,该阶段会返回上一个阶段的任务执行结果,如果前面的阶段执行异常,那么会返回该阶段的异常执行结果
    public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);
    
/**
 * CompletableFuture 异常处理
 *
 * @author zdp
 * @date 2022-07-25 17:51
 */
public class CompletableExceptionallyExample {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //由调用线程执行whenComplete,当前面的阶段异常时,whenComplete阶段会返回异常信息,当前面的阶段正常执行,whenComplete阶段会正常返回结果
        CompletableFuture<String> whenComplete =
                CompletableFuture.supplyAsync(() -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行supplyAsync....");
                    return "return result..";
                }).thenApply(resultOne -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenApply....");
                    return "return " + resultOne + "..";
                }).whenComplete((result, exception) -> {
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行whenComplete....");
                    if (exception != null) {
                        System.out.println("执行异常.." + exception.getMessage());
                    }
                }
        );
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了whenComplete....结果是: {" + whenComplete.get() + "}");
        System.out.println("================================================================");

        //由默认线程池执行whenCompleteAsync,当前面的阶段异常时,whenCompleteAsync阶段会返回异常信息,当前面的阶段正常执行,whenCompleteAsync阶段会正常返回结果
        CompletableFuture<String> whenCompleteAsync =
                CompletableFuture.supplyAsync(() -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行supplyAsync....");
                    return "return result..";
                }).thenApply(resultOne -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenApply....");
                    return "return " + resultOne + "..";
                }).whenCompleteAsync((result, exception) -> {
                        System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行whenCompleteAsync....");
                        if (exception != null) {
                            System.out.println("执行异常.." + exception.getMessage());
                        }
                    }
                );
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了whenCompleteAsync....结果是: {" + whenCompleteAsync.get() + "}");
        System.out.println("================================================================");

        //由指定的线程池执行whenCompleteAsync,当前面的阶段异常时,whenCompleteAsync阶段会返回异常信息,当前面的阶段正常执行,whenCompleteAsync阶段会正常返回结果
        CompletableFuture<String> whenCompleteAsyncExecutor =
                CompletableFuture.supplyAsync(() -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行supplyAsync....");
                    return "return result..";
                }).thenApply(resultOne -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenApply....");
                    return "return " + resultOne + "..";
                }).whenCompleteAsync((result, exception) -> {
                        System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行whenCompleteAsyncExecutor....");
                        if (exception != null) {
                            System.out.println("执行异常.." + exception.getMessage());
                        }
                    }, Executors.newFixedThreadPool(2)
                );
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了whenCompleteAsyncExecutor....结果是: {" + whenCompleteAsyncExecutor.get() + "}");
        System.out.println("================================================================");

        //由调用线程执行handle,当前面的阶段异常时,handle阶段会返回异常信息,当前面的阶段正常执行,handle阶段会返回handle阶段执行的结果,handle中的任务执行参数是上一个阶段执行的结果
        CompletableFuture<String> handle =
                CompletableFuture.supplyAsync(() -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行supplyAsync....");
                    return "return begin..";
                }).thenApply(resultOne -> {
                    int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenApply....");
                    return "return one..";
                }).handle((result, exception) -> {
                        System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行handle....");
                        if (exception != null) {
                            System.out.println("执行异常.." + exception.getMessage());
                            return "handle执行异常了....";
                        }
                        return result + "handle..正常执行了..";
                    }
                );
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了handle....结果是: {" + handle.get() + "}");
        System.out.println("================================================================");

        //由默认线程池执行handle,当前面的阶段异常时,handle阶段会返回异常信息,当前面的阶段正常执行,handle阶段会返回handle阶段执行的结果,handle中的任务执行参数是上一个阶段执行的结果
        CompletableFuture<String> handleAsync =
                CompletableFuture.supplyAsync(() -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行supplyAsync....");
                    return "return begin..";
                }).thenApply(resultOne -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenApply....");
                    return "return one..";
                }).handleAsync((result, exception) -> {
                        System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行handleAsync....");
                        if (exception != null) {
                            System.out.println("执行异常.." + exception.getMessage());
                            return "handleAsync执行异常了....";
                        }
                        return result + "handleAsync..正常执行了..";
                    }
                );
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了handleAsync....结果是: {" + handleAsync.get() + "}");
        System.out.println("================================================================");

        //由指定线程池执行handle,当前面的阶段异常时,handle阶段会返回异常信息,当前面的阶段正常执行,handle阶段会返回handle阶段执行的结果,handle中的任务执行参数是上一个阶段执行的结果
        CompletableFuture<String> handleAsyncExecutor =
                CompletableFuture.supplyAsync(() -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行supplyAsync....");
                    return "return begin..";
                }).thenApply(resultOne -> {
                    int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenApply....");
                    return "return one..";
                }).handleAsync((result, exception) -> {
                        System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行handleAsyncExecutor....");
                        if (exception != null) {
                            System.out.println("执行异常.." + exception.getMessage());
                            return "handleAsyncExecutor执行异常了....";
                        }
                        return result + "handleAsyncExecutor..正常执行了..";
                    }, Executors.newFixedThreadPool(2)
                );
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了handleAsyncExecutor....结果是: {" + handleAsyncExecutor.get() + "}");
        System.out.println("================================================================");

        //由调用线程来执行exceptionally,当前面的阶段正常执行时,该阶段会返回上一个阶段的任务执行结果,如果前面的阶段执行异常,那么会返回该阶段的异常执行结果
        CompletableFuture<String> exceptionally =
                CompletableFuture.supplyAsync(() -> {
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行supplyAsync....");
                    //throw new RuntimeException("supplyAsync execute error...");
                    return "return begin..";
                }).thenApply(resultOne -> {
                    //int i = 1/0;
                    System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行thenApply....");
                    return "return one..";
                }).exceptionally(exception -> {
                        System.out.println("由线程【" + Thread.currentThread().getName() +"】 执行exceptionally....");
                        if (exception != null) {
                            System.out.println(exception.getMessage());
                            for (StackTraceElement el : exception.getStackTrace()) {
                                System.err.println(el);
                            }
                            return "exceptionally 执行异常了....";
                        }
                        return "exceptionally 正常执行了..";
                    }
                );
        System.out.println("线程【" + Thread.currentThread().getName() +"】 执行到了exceptionally....结果是: {" + exceptionally.get() + "}");
        System.out.println("================================================================");
    }

}
  • toCompletableFuture
//返回与上一个阶段保持一致的CCompletableFuture
public CompletableFuture<T> toCompletableFuture();
/**
 * CompletableFuture.toCompletableFuture 返回与上一个阶段一致的CompletableFuture
 *
 * @author zdp
 * @date 2022-07-26 14:30
 */
public class CompletableFutureToExample {

    public static int var = 5;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //保持与上阶段相同的完成属性。如果上阶段已经是一个正常完成的CompletableFuture,则此方法会返回上阶段任务执行结果
        CompletableFuture<Integer> completableFuture =
            CompletableFuture.supplyAsync(() -> var)
                .thenApply(result -> {
                    //int i = 1/0;
                    return result + 10;
                }).handle((result, exception) -> {
                    if (exception != null) {
                        return 0;
                    }
                    return result + 20;
                }).toCompletableFuture();
        System.out.println(completableFuture.get());
    }

}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值