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

方法一

CompletableFuture whenComplete(BiConsumer action)
1、使用

System.out.println("===1、使用CompletableFuture whenComplete(BiConsumer action)====================================================================================");
// 1、使用CompletableFuture whenComplete(BiConsumer 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 zeroat 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 zeroat 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 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 zeroat 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 zeroat 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 action,Executor executor)
1、使用

        System.out.println("===3、CompletionStage whenCompleteAsync(BiConsumer action,Executor executor)===================================================================================");
// 3、CompletionStage whenCompleteAsync(BiConsumer 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 fn)
1、使用

System.out.println("===4、CompletableFuture exceptionally(Function fn)===================================================================================");
//4、CompletableFuture exceptionally(Function 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 fn)
2、CompletableFuture handleAsync(BiFunction fn)
3、CompletableFuture handleAsync(BiFunction fn, Executor executor)
注: handle和但whenComplete的区别为:handler中可以对结果进行处理,而whenComplete不能

handleAsync方法

1、使用

System.out.println("CompletableFuture handle(BiFunction 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 fn)
CompletableFuture thenApplyAsync(Function fn)
CompletableFuture thenApplyAsync(Function fn,Executor executor)
2、thenAccept:可以接收前一个CompletableFuture 任务返回值,执行then后不能返回结果
CompletableFuture thenAccept(Consumer action)
CompletableFuture thenAcceptAsync(Consumer action)
CompletableFuture thenAcceptAsync(Consumer 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 other,BiFunction fn)
CompletableFuture thenCombineAsync(CompletionStage other,BiFunction fn)
CompletableFuture thenCombineAsync(CompletionStage other,BiFunction fn, Executor executor)

2、thenAcceptBoth 能够接受前两个任务的返值作为参数任务三的参数,并且任务三没有有返回值
CompletableFuture thenAcceptBoth(CompletionStage other,BiConsumer action)
CompletableFuture thenAcceptBothAsync(CompletionStage other,BiConsumer action)
CompletableFuture thenAcceptBothAsync(CompletionStage other,BiConsumer 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 other, Function fn) CompletableFuture applyToEitherAsync(CompletionStage other, Function fn) CompletableFuture applyToEitherAsync(CompletionStage other, Function fn, Executor executor) 2、thenAcceptBoth 能够接受前两个任务先执行完成的返回值作为参数任务三的参数,并且任务三没有有返回值 CompletableFuture acceptEither(CompletionStage other, Consumer action) CompletableFuture acceptEitherAsync(CompletionStage other, Consumer action) CompletableFuture acceptEitherAsync(CompletionStage other, Consumer 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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部