您的位置:首页 > 游戏 > 手游 > CompletableFutuer异步回调

CompletableFutuer异步回调

2024/10/6 6:02:54 来源:https://blog.csdn.net/m0_68082638/article/details/142223093  浏览:    关键词:CompletableFutuer异步回调

CompletableFuture的类关系

对于 Future接口都比较熟悉了.主要介绍下CompletionStage接口.

CompletionStage接口代表异步计算过程中的某一个阶段,一个阶段完成后会进入另一个阶段.一个阶段可以理解为一个子任务,每个子任务会包装一个Java函数式接口实例,表示该子任务要执行的操作.

CompletionStage接口

顾名思义,Stage是阶段的意思.CompletionStage代表某个同步或者异步计算的一个阶段,或者是一系列异步任务中的一个子任务.

每个CompletionStage子任务所包装的可以是一个Function Consumer Runnable函数式接口.

1:Function

Function接口的特点,有输入有输出,包装了Function实例的CompletionStage的子任务需要输入一个参数,并会产生一个输出结果到下一步.

2:Runnable

Runnable接口的特点,是无输入无输出,包装了Runnable实例的CompletionStage的子任务既不需要任何输入也不会产生任何输出.

3:Consumer

Consumer接口的特点是,有输入无输出.包装了Consumer实例的CompletionStage的子任务需要输入一个参数,但不会产生任何输出.

runAsync和supplyAsync创建子任务

CompletionStage子任务的创建是通过CompletableFuture完成的.CompletableFuture定义了一组方法用于创建CompletionStage子任务.基础方法如下.

 //包装一个Runnable实例,使用ForkJoinPool.commonPool()线程池来执行public static CompletableFuture<Void> runAsync(Runnable runnable)//包装一个Runnable实例,指定线程池执行.public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor) //包装一个Supplier实例,使用ForkJoinPool.commonPool()线程池来执行public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)//包装一个Supplier实例,指定线程池执行.public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)

实例如下

public class CompletableFutureTest {public static void main(String[] args) throws Exception {//创建一个无输入值无返回值的异步子任务.CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();System.out.println("运行结束");}});//等待异步任务执行完成.future.get(2, TimeUnit.SECONDS);//创建一个无输入有返回值的异步子任务.CompletableFuture<Long> future1 = CompletableFuture.supplyAsync(() -> {long start = System.currentTimeMillis();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();System.out.println("运行结束");}return System.currentTimeMillis() - start;});//等待异步任务执行完成.Long aLong = future1.get(2, TimeUnit.SECONDS);System.out.println("异步执行耗时--" + aLong / 1000);}
}
设置子任务的回调钩子

 可以为CompletionStage子任务设置特定的回调钩子,当计算计算结果完成或者抛出异常的时候执行这些特定的回调钩子.

//设置子任务完成的回调钩子.
public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)//设置子任务完成的回调钩子,可能不在同一个线程.
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)//设置子任务完成的回调钩子,提交给线程池执行.
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)

实例如下

public class CompletableFutureTest2 {public static void main(String[] args) throws ExecutionException, InterruptedException {CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("发生异常");throw new RuntimeException("我是异常..");});//异步执行完成的回调钩子.future.whenComplete(new BiConsumer<Void, Throwable>() {@Overridepublic void accept(Void unused, Throwable throwable) {System.out.println("执行完成.");}});//抛出异常回调钩子.future.exceptionally(new Function<Throwable, Void>() {@Overridepublic Void apply(Throwable throwable) {System.out.println("执行失败"+throwable.getMessage());return null;}});//异步获取结果.System.out.println(future.get());}
}
调用Handle()方法统一处理异常和结果

除了可以通过回调函数处理以外,还可以通过handle方法统一处理结果和异常.

handle方法有三个重载版本.

//在执行任务的同一个线程处理异常和结果.
public <U> CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn)
//可能不在同一个线程处理异常和结果.
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
//在指定线程池处理异常和结果
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
案例如下
public class CompletableFutureTest3 {public static void main(String[] args) throws ExecutionException, InterruptedException {CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("发生异常");throw new RuntimeException("我是异常..");});future.handle(new BiFunction<Void, Throwable, Object>() {@Overridepublic Object apply(Void unused, Throwable throwable) {if (null == throwable) {System.out.println("没有发生异常.");}else {System.out.println("发生了异常.");}return null;}});System.out.println(future.get());}
}

走的多了自然就成了路.我走在四下无人的地方,我何来路可选,何来言弃一说.

如果大家喜欢我的分享的话.关注下我的微信公众号

心有九月星辰

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com