百练成钢02之异步编排(CompletableFuture)使用笔记

一、CompletableFuture创建

CompletableFuture提供了4中静态方法创建CompletableFuture对象,返回异步完成的新CompletableFuture,分别是:

1、CompletableFuture runAsync(Runnable runnable):线程执行无返回值,使用CompletableFuture默认的线程池执行
2、CompletableFuture runAsync(Runnable runnable, Executor executor):线程执行无返回值,使用传入的线程池
3、CompletableFuture supplyAsync(Supplier supplier):线程执行有返回值,使用CompletableFuture默认的线程池执行
4、CompletableFuture supplyAsync(Supplier supplier,Executor executor):线程执行有返回值,使用传入的线程池
注:
runAsync和supplyAsync区别:
runAsync无线程执行返回值,supplyAsync有线程执行返回值

方式一

CompletableFuture runAsync(Runnable runnable)
1、使用

CompletableFuture<Void> runAsyncFuture1 = CompletableFuture.runAsync(() -> System.out.println("打印当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName()));
System.out.println("等待线程执行完,获取CompletableFuture.runAsync响应结果"+runAsyncFuture1.get());

2、输出结果

打印当前运行线程,线程ID=20,线程名=ForkJoinPool.commonPool-worker-25
等待线程执行完,获取CompletableFuture.runAsync响应结果null

方式二

CompletableFuture runAsync(Runnable runnable, Executor executor)
1、使用

ThreadFactory threadFactory1 = runnable -> {
    Thread thread = new Thread(runnable);
    thread.setName("[threadFactory1]");
    return thread;
};
ThreadPoolExecutor executor1 = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(10) , threadFactory1, new ThreadPoolExecutor.AbortPolicy());
CompletableFuture<Void> runAsyncFuture2 = CompletableFuture.runAsync(() -> System.out.println("打印当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName()), executor1);
System.out.println("等待线程执行完,获取CompletableFuture.runAsync响应结果"+runAsyncFuture2.get());
executor1.shutdown();

2、结果输出

打印当前运行线程,线程ID=21,线程名=[threadFactory1]
等待线程执行完,获取CompletableFuture.runAsync响应结果nu

方式三

CompletableFuture supplyAsync(Supplier supplier)
1、使用

CompletableFuture<Integer> integerSupplyAsynFuture1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("打印当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
    return 10;
});
System.out.println("等待线程执行完,获取CompletableFuture.supplyAsync响应结果"+integerSupplyAsynFuture1.get());

2、结果输出

打印当前运行线程,线程ID=20,线程名=ForkJoinPool.commonPool-worker-25
等待线程执行完,获取CompletableFuture.supplyAsync响应结果10

方式四

CompletableFuture supplyAsync(Supplier supplier,Executor executor)
1、使用

ThreadPoolExecutor executor2 = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(10) , threadFactory2, new ThreadPoolExecutor.AbortPolicy());
CompletableFuture<Integer> integerSupplyAsynFuture2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("打印当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
    return 10;
},executor2);
System.out.println("等待线程执行完,获取CompletableFuture.supplyAsync响应结果"+integerSupplyAsynFuture2.get());
executor2.shutdown();

2、结果输出

打印当前运行线程,线程ID=22,线程名=[threadFactory2]
等待线程执行完,获取CompletableFuture.supplyAsync响应结果10

注: 以上创建CompletableFuture就会执行线程

public static CompletableFuture<Void> runAsync(Runnable runnable) {
	return asyncRunStage(asyncPool, runnable);
}

public static CompletableFuture<Void> asyncRunStage(Executor e, Runnable f) {
	if (f == null) throw new NullPointerException();
	CompletableFuture<Void> d = new CompletableFuture<Void>();
	e.execute(new AsyncRun(d, f));
	return d;
}

二、计算完成时回调方法

方法介绍

1、CompletableFuture whenComplete(BiConsumer<? super T, ? super Throwable> action)
2、CompletionStage whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)
3、CompletionStage whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,Executor executor)
4、CompletableFuture exceptionally(Function<Throwable, ? extends T> fn)
:使用whenComplete不能改变返回结果,使用exceptionally根据异常处理情况可以更改。
whenComplete 可以处理正常和异常的计算结果,exceptionally 处理异常情况
方法加Async和不加Async的区别
a、不加Async是执行当前任务的线程执行继续执行 whenComplete 的任务(非默认线程池和自定义线程池,可以理解为main线程)
b、加Async是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。

方法一

CompletableFuture whenComplete(BiConsumer<? super T, ? super Throwable> action)
1、使用

System.out.println("===1、使用CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)====================================================================================");
// 1、使用CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
CompletableFuture<String> whenCompleteFuture1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("打印CompletableFuture.runAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1/0;
    return "CompletableFuture.supplyAsync";
}).whenComplete((result, exception) -> {
    if (result != null){
        System.out.println("打印线程执行完成的结果参数:返回值=" + result + ",异常参数=" + exception);
    }
    if (exception !=null){
        System.out.println("打印线程执行完成的结果参数:返回值=" + result + ",异常参数=" + exception);
    }
    System.out.println("打印whenComplete当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
});
System.out.println("打印输出结果whenCompleteFuture1:"+whenCompleteFuture1.get());

2、结果输出

任务正常执行

===1、使用CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)====================================================================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印线程执行完成的结果参数:返回值=CompletableFuture.supplyAsync,异常参数=null
打印whenComplete当前运行线程,线程ID=1,线程名=main
打印输出结果whenCompleteFuture1:CompletableFuture.supplyAsync

任务异常执行

===1、使用CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)====================================================================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印线程执行完成的结果参数:返回值=null,异常参数=java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
打印whenComplete当前运行线程,线程ID=1,线程名=main
`Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
	at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908)
	at cn.study.zgm.thread01.completablefuture.create.CompletableFutureTest.main(CompletableFutureTest.java:111)
Caused by: java.lang.ArithmeticException: / by zero
	at cn.study.zgm.thread01.completablefuture.create.CompletableFutureTest.lambda$main$6(CompletableFutureTest.java:100)
	at java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1604)
	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
	at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1596)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1067)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1703)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:172)`

结果说明:CompletableFuture.runAsync中执行的线程CompletableFuture默认线程池调度的,而whenComplete中线程执行是使用main

方法二

CompletionStage whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)
1、使用

CompletableFuture<String> whenCompleteAsyncFuture2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("打印CompletableFuture.runAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1/0;
    return "CompletableFuture.supplyAsync";
}).whenCompleteAsync((result, exception) -> {
    if (result != null){
        System.out.println("打印线程执行完成的结果参数:返回值=" + result + ",异常参数=" + exception);
    }
    if (exception !=null){
        System.out.println("打印线程执行完成的结果参数:返回值=" + result + ",异常参数=" + exception);
    }
    System.out.println("打印whenCompleteAsync(p1)当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
});
System.out.println("打印输出结果whenCompleteAsyncFuture2:"+whenCompleteAsyncFuture2.get());

2、结果输出

任务正常执行

===2、使用CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)===================================================================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印线程执行完成的结果参数:返回值=CompletableFuture.supplyAsync,异常参数=null
打印whenCompleteAsync(p1)当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印输出结果whenCompleteAsyncFuture2:CompletableFuture.supplyAsyn

任务异常执行

===2、使用CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)===================================================================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印线程执行完成的结果参数:返回值=null,异常参数=java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
打印whenCompleteAsync(p1)当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
`Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
	at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908)
	at cn.study.zgm.thread01.completablefuture.create.CompletableFutureTest.main(CompletableFutureTest.java:136)
Caused by: java.lang.ArithmeticException: / by zero
	at cn.study.zgm.thread01.completablefuture.create.CompletableFutureTest.lambda$main$8(CompletableFutureTest.java:125)
	at java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1604)
	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
	at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1596)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1067)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1703)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:172)`

结果说明:whenCompleteAsync不传线程池,使用CompletableFuture的默认线程池

方法三

CompletionStage whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,Executor executor)
1、使用

        System.out.println("===3、CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,Executor executor)===================================================================================");
// 3、CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,Executor executor)
ThreadFactory threadFactory3 = runnable -> {
    Thread thread = new Thread(runnable);
    thread.setName("[threadFactory3]");
    return thread;
};
ThreadPoolExecutor executor3 = new ThreadPoolExecutor(5, 10, 10, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(10) , threadFactory3, new ThreadPoolExecutor.AbortPolicy());
CompletableFuture<String> whenCompleteAsyncFuture3 = CompletableFuture.supplyAsync(() -> {
    System.out.println("打印CompletableFuture.runAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1/0;
    return "CompletableFuture.supplyAsync";
}).whenCompleteAsync((result, exception) -> {
    if (result != null){
        System.out.println("打印线程执行完成的结果参数:返回值=" + result + ",异常参数=" + exception);
    }
    if (exception !=null){
        System.out.println("打印线程执行完成的结果参数:返回值=" + result + ",异常参数=" + exception);
    }
    System.out.println("打印whenCompleteAsync(p1,p2) 当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
},executor3);
System.out.println("打印输出结果whenCompleteAsyncFuture3:"+whenCompleteAsyncFuture3.get());

2、结果输出

===3、CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,Executor executor)===================================================================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印线程执行完成的结果参数:返回值=CompletableFuture.supplyAsync,异常参数=null
打印whenCompleteAsync(p1,p2) 当前运行线程,线程ID=25,线程名=[threadFactory3]
打印输出结果whenCompleteAsyncFuture3:CompletableFuture.supplyAsync

结果说明:传入了线程池,调用whenCompleteAsync使用传入线程池创建的线程

方法四

CompletableFuture exceptionally(Function<Throwable, ? extends T> fn)
1、使用

System.out.println("===4、CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)===================================================================================");
//4、CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)
CompletableFuture<String> exceptionallyFuture4 = CompletableFuture.supplyAsync(() -> {
    System.out.println("打印CompletableFuture.runAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1/0;
    return "CompletableFuture.supplyAsync";
}).exceptionally(exception -> {
    if (exception != null) {
        System.out.println("打印线程执行完成的结果参数:异常参数=" + exception);
    }
    System.out.println("exceptionally当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
    return exception != null ? exception.toString() : "null";
});
System.out.println("打印输出结果exceptionallyFuture4:"+exceptionallyFuture4.get());

2、结果输出

任务正常执行

===4、CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)===================================================================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印输出结果exceptionallyFuture4:CompletableFuture.supplyAsync

任务异常执行

===4、CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)===================================================================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印线程执行完成的结果参数:异常参数=java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
exceptionally当前运行线程,线程ID=1,线程名=main
打印输出结果exceptionallyFuture4:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero

结果说明:如果任务执行异常,则会执行exceptionally中的任务,并且可以对异常作为任务参数进行处理。

三、handle方法

CompletableFuture中handle相关方法如下:

1、CompletableFuture handle(BiFunction<? super T, Throwable, ? extends U> fn)
2、CompletableFuture handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
3、CompletableFuture handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
注: handle和但whenComplete的区别为:handler中可以对结果进行处理,而whenComplete不能

handleAsync方法

1、使用

System.out.println("CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn)");
CompletableFuture<String> handleCompletableFuture = CompletableFuture.supplyAsync(() -> {
    System.out.println("打印CompletableFuture.runAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
    int i = 1/0;
    return "CompletableFuture.supplyAsync";
}).handle((result, exception) -> {
    if (result != null){
        System.out.println("打印线程执行完成的结果参数:返回值=" + result + ",异常参数=" + exception);
    }
    if (exception !=null){
        System.out.println("打印线程执行完成的结果参数:返回值=" + result + ",异常参数=" + exception);
    }
    System.out.println("打印handle当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
    return "handle";
});
System.out.println("打印输出结果handleCompletableFuture="+handleCompletableFuture.get());

2、结果输出

CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn)
打印CompletableFuture.runAsync当前运行线程,线程ID=20,线程名=ForkJoinPool.commonPool-worker-25
打印线程执行完成的结果参数:返回值=null,异常参数=java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
打印handle当前运行线程,线程ID=20,线程名=ForkJoinPool.commonPool-worker-25
打印输出结果handleCompletableFuture=handle

四、线程串行化方法

方法介绍

1、thenApply:可以接收前一个CompletableFuture 任务返回值,执行then后能返回结果
CompletableFuture thenApply(Function<? super T,? extends U> fn)
CompletableFuture thenApplyAsync(Function<? super T,? extends U> fn)
CompletableFuture thenApplyAsync(Function<? super T,? extends U> fn,Executor executor)
2、thenAccept:可以接收前一个CompletableFuture 任务返回值,执行then后不能返回结果
CompletableFuture thenAccept(Consumer<? super T> action)
CompletableFuture thenAcceptAsync(Consumer<? super T> action)
CompletableFuture thenAcceptAsync(Consumer<? super T> action,Executor executor)
3、thenRun: 不能接收前一个CompletableFuture 任务返回值,执行then后不能返回结果
CompletableFuture thenRun(Runnable action)
CompletableFuture thenRunAsync(Runnable action)
CompletableFuture thenRunAsync(Runnable action,Executor executor)
:三者都是等待CompletableFuture前置任务执行完后,才会执行then中任务

方法使用

1、使用

 System.out.println("===1、CompletableFuture.supplyAsync=========================================");
 CompletableFuture<Void> thenRunCompletableFuture = CompletableFuture.supplyAsync(() -> {
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
     System.out.println("打印CompletableFuture.runAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
     return "CompletableFuture.supplyAsync";
 }).thenRunAsync(() -> {
     System.out.println("打印thenRun当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
 });
 System.out.println("返回thenRunCompletableFuture输出结果="+thenRunCompletableFuture.get());

 System.out.println("===2、CompletableFuture.thenAccept=========================================");
 CompletableFuture<Void> thenAcceptCompletableFuture = CompletableFuture.supplyAsync(() -> {
     try {
         Thread.sleep(1000);
     } catch (InterruptedException e) {
         e.printStackTrace();
     }
     System.out.println("打印CompletableFuture.runAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
     return "CompletableFuture.supplyAsync";
 }).thenAcceptAsync((result) -> {
     System.out.println("打印thenRun当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
     if (result!=null){
         System.out.println("打印CompletableFuture.supplyAsync执行结果="+result);
     }
 });
 System.out.println("返回thenRunCompletableFuture输出结果="+thenAcceptCompletableFuture.get());

 System.out.println("===3、CompletableFuture.thenAccept=========================================");
 CompletableFuture<String> thenApplyCompletableFuture = CompletableFuture.supplyAsync(() -> {
     try {
         Thread.sleep(1000);
     } catch (InterruptedException e) {
         e.printStackTrace();
     }
     System.out.println("打印CompletableFuture.runAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
     return "CompletableFuture.supplyAsync";
 }).thenApply((result) -> {
     System.out.println("打印thenRun当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
     if (result!=null){
         System.out.println("打印CompletableFuture.supplyAsync执行结果="+result);
     }
     return "thenApply";
 });
 System.out.println("返回thenRunCompletableFuture输出结果="+thenApplyCompletableFuture.get());

2、结果输出

===1、CompletableFuture.supplyAsync=========================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印thenRun当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
返回thenRunCompletableFuture输出结果=null
===2、CompletableFuture.thenAccept=========================================
打印CompletableFuture.runAsync当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印thenRun当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印CompletableFuture.supplyAsync执行结果=CompletableFuture.supplyAsync
返回thenRunCompletableFuture输出结果=null
===3、CompletableFuture.thenAccept=========================================
打印CompletableFuture.runAsync当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印thenRun当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印CompletableFuture.supplyAsync执行结果=CompletableFuture.supplyAsync
返回thenRunCompletableFuture输出结果=thenApply

五、两任务组合-都要完成

方法介绍

任务一、任务二、两者都执行完成后,再执行任务三
1、thenCombine 能够接受前两个任务的返值作为参数任务三的参数,并且任务三可以有返回值
CompletableFuture thenCombine(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn)
CompletableFuture thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn)
CompletableFuture thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn, Executor executor)

2、thenAcceptBoth 能够接受前两个任务的返值作为参数任务三的参数,并且任务三没有有返回值
CompletableFuture thenAcceptBoth(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action)
CompletableFuture thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action)
CompletableFuture thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action, Executor executor)

3、runAfterBoth 不能接受前两个任务的返值作为参数任务三的参数,并且任务三没有有返回值
CompletableFuture runAfterBoth(CompletionStage<?> other,Runnable action) CompletableFuture runAfterBothAsync(CompletionStage<?> other,Runnable action)
CompletableFuture runAfterBothAsync(CompletionStage<?> other,Runnable action,Executor executor)

方法使用

以下以thenCombineAsync、runAfterBothAsync、runAfterBothAsync方法介绍
1、使用

CompletableFuture<String> supplyAsyncCompletableFuture1 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("打印CompletableFuture.runAsync1当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
    return "CompletableFuture.supplyAsync";
});
CompletableFuture<String> supplyAsyncCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("打印CompletableFuture.runAsync2当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
    return "CompletableFuture.supplyAsync";
});
System.out.println("===1、thenCombineAsync ===========================================================");
CompletableFuture<String> thenCombineAsyncFuture = supplyAsyncCompletableFuture1.thenCombineAsync(supplyAsyncCompletableFuture2, (o1, o2) -> {
    System.out.println("打印任务1结果="+o1+",任务2结果="+o2);
    System.out.println("打印thenCombineAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
    return "o1输出结果=" + o1 + " + o2输出结果=" + o2;
});
System.out.println("thenCombineAsyncFuture:"+thenCombineAsyncFuture.get());
System.out.println("===2、thenAcceptBothFuture ===========================================================");
CompletableFuture<Void> thenAcceptBothFuture = supplyAsyncCompletableFuture1.thenAcceptBothAsync(supplyAsyncCompletableFuture2, (o1, o2) -> {
    System.out.println("打印任务1结果="+o1+",任务2结果="+o2);
    System.out.println("打印thenCombineAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
});
System.out.println("打印thenAcceptBothFuture输出结果:"+thenAcceptBothFuture.get());
System.out.println("===3、thenAcceptBothAsync ===========================================================");
CompletableFuture<Void> runAfterBothAsyncFuture = supplyAsyncCompletableFuture1.runAfterBothAsync(supplyAsyncCompletableFuture2, () -> {
    System.out.println("打印thenCombineAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
});
System.out.println("打印runAfterBothAsyncFuture输出结果:"+runAfterBothAsyncFuture.get());

System.out.println("===main.sleep(2000)==========================================================================");
Thread.sleep(2000);

2、结果输出

===1、thenCombineAsync ===========================================================
打印CompletableFuture.runAsync1当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印CompletableFuture.runAsync2当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印任务1结果=CompletableFuture.supplyAsync,任务2结果=CompletableFuture.supplyAsync
打印thenCombineAsync当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
thenCombineAsyncFuture:o1输出结果=CompletableFuture.supplyAsync + o2输出结果=CompletableFuture.supplyAsync
===2、thenAcceptBothFuture ===========================================================
打印任务1结果=CompletableFuture.supplyAsync,任务2结果=CompletableFuture.supplyAsync
打印thenCombineAsync当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印thenAcceptBothFuture输出结果:null
===3、thenAcceptBothAsync ===========================================================
打印thenCombineAsync当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印runAfterBothAsyncFuture输出结果:null
===main.sleep(2000)==========================================================================

六、两任务组合-任一任务完成

方法介绍

任务一、任务二、两者任一个执行完成,立即执行任务
1、applyToEither 能够接受前两个任务先执行完成的返回值作为参数任务三的参数,并且任务三可以有返回值
CompletableFuture applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn) CompletableFuture applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn) CompletableFuture applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor) 2、thenAcceptBoth 能够接受前两个任务先执行完成的返回值作为参数任务三的参数,并且任务三没有有返回值 CompletableFuture acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action) CompletableFuture acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action) CompletableFuture acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action,Executor executor) 3、runAfterBoth 不能接受前接受前两个任务先执行完成的返回值作为参数任务三的参数,并且任务三没有有返回值 CompletableFuture runAfterEither(CompletionStage<?> other, Runnable action)
CompletableFuture runAfterEitherAsync(CompletionStage<?> other, Runnable action) CompletableFuture runAfterEitherAsync(CompletionStage<?> other, Runnable action,Executor executor)

方法使用

以下为applyToEitherAsync、acceptEitherAsync、runAfterEitherAsync方法介绍
1、使用

CompletableFuture<String> supplyAsyncFuture1 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("打印CompletableFuture.runAsync1当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
    return "CompletableFuture.supplyAsync1";
});
CompletableFuture<String> supplyAsyncFuture2 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("打印CompletableFuture.runAsync2当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
    return "CompletableFuture.supplyAsync2";
});
System.out.println("===1、applyToEitherAsync==============================================================");
// 注意因为是两者任一执行完,所以此处参数先执行完成任务的返回值
CompletableFuture<String> applyToEitherAsyncFuture = supplyAsyncFuture1.applyToEitherAsync(supplyAsyncFuture2, (o1) -> {
    System.out.println("打印任务结果=" + o1);
    System.out.println("打印applyToEitherAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
    return "o1输出结果=" + o1;
});
System.out.println("打印applyToEitherAsyncFuture输出结果:"+applyToEitherAsyncFuture.get());
System.out.println("===2、acceptEitherAsync==============================================================");
// 注意因为是两者任一执行完,所以此处参数先执行完成任务的返回值
CompletableFuture<Void> acceptEitherAsyncFuture = supplyAsyncFuture1.acceptEitherAsync(supplyAsyncFuture2, (o1) -> {
    System.out.println("打印任务结果=" + o1);
    System.out.println("打印acceptEitherAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
});
System.out.println("acceptEitherAsyncFuture:"+acceptEitherAsyncFuture.get());
System.out.println("===3、runAfterEitherAsync==============================================================");
// 注意因为是两者任一执行完,所以此处参数先执行完成任务的返回值
CompletableFuture<Void> runAfterEitherAsyncFuture = supplyAsyncFuture1.runAfterEitherAsync(supplyAsyncFuture2, () -> {
    System.out.println("打印runAfterEitherAsync当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
});
System.out.println("runAfterEitherAsyncFuture:"+runAfterEitherAsyncFuture.get());

System.out.println("===main.sleep(2000)==========================================================================");
Thread.sleep(2000);

2、使用

===1、applyToEitherAsync==============================================================
打印CompletableFuture.runAsync2当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印任务结果=CompletableFuture.supplyAsync2
打印applyToEitherAsync当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印applyToEitherAsyncFuture输出结果:o1输出结果=CompletableFuture.supplyAsync2
===2、acceptEitherAsync==============================================================
打印任务结果=CompletableFuture.supplyAsync2
打印acceptEitherAsync当前运行线程,线程ID=24,线程名=ForkJoinPool.commonPool-worker-11
acceptEitherAsyncFuture:null
===3、runAfterEitherAsync==============================================================
打印runAfterEitherAsync当前运行线程,线程ID=24,线程名=ForkJoinPool.commonPool-worker-11
runAfterEitherAsyncFuture:null
===main.sleep(2000)==========================================================================
打印CompletableFuture.runAsync1当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25

七、多任务组合

方法介绍

1、static CompletableFuture allOf(CompletableFuture<?>… cfs)

2、static CompletableFuture anyOf(CompletableFuture<?>… cfs)

方法使用

1、使用

        System.out.println("===CompletableFuture.allOf===========================");
CompletableFuture<String> supplyAsyncFuture1 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("打印CompletableFuture.runAsync1当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
    return "CompletableFuture.supplyAsync1";
});
CompletableFuture<String> supplyAsyncFuture2 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("打印CompletableFuture.runAsync2当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
    return "CompletableFuture.supplyAsync2";
});
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(supplyAsyncFuture1, supplyAsyncFuture2);
System.out.println("打印allOfFuture输出结果="+allOfFuture.get());
System.out.println("打印supplyAsyncFuture1输出结果="+supplyAsyncFuture1.get());
System.out.println("打印supplyAsyncFuture2输出结果="+supplyAsyncFuture2.get());

Thread.sleep(5000);
System.out.println("===CompletableFuture.anyOf===========================");
CompletableFuture<String> supplyAsyncFuture3 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("打印CompletableFuture.runAsync3当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
    return "CompletableFuture.supplyAsync3";
});
CompletableFuture<String> supplyAsyncFuture4 = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("打印CompletableFuture.runAsync4当前运行线程,线程ID=" + Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName());
//            int i = 1 / 0;
    return "CompletableFuture.supplyAsync4";
});
CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(supplyAsyncFuture3, supplyAsyncFuture4);
System.out.println("打印anyOfFuture输出结果="+anyOfFuture.get());
System.out.println("打印supplyAsyncFuture3输出结果="+supplyAsyncFuture3.get());
System.out.println("打印supplyAsyncFuture4输出结果="+supplyAsyncFuture4.get());
Thread.sleep(5000);

2、结果输出

===CompletableFuture.allOf===========================
打印CompletableFuture.runAsync2当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印CompletableFuture.runAsync1当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印allOfFuture输出结果=null
打印supplyAsyncFuture1输出结果=CompletableFuture.supplyAsync1
打印supplyAsyncFuture2输出结果=CompletableFuture.supplyAsync2
===CompletableFuture.anyOf===========================
打印CompletableFuture.runAsync4当前运行线程,线程ID=23,线程名=ForkJoinPool.commonPool-worker-18
打印anyOfFuture输出结果=CompletableFuture.supplyAsync4
打印CompletableFuture.runAsync3当前运行线程,线程ID=22,线程名=ForkJoinPool.commonPool-worker-25
打印supplyAsyncFuture3输出结果=CompletableFuture.supplyAsync3
打印supplyAsyncFuture4输出结果=CompletableFuture.supplyAsync4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值