java 8引入的CompletableFuture的使用

       最近在学习如何使用CompletableFuture这个新的并发类,通过搜索在DZone上发现了一篇文件,介绍使用CompletableFuture的20个例子,链接如下:https://dzone.com/articles/20-examples-of-using-javas-completablefuture。

       每次JDK推出一个新的类/数据结构之后,我想很多人的第一个问题是,这个类/数据结构在哪种场景下使用最合适,它能用来解决什么问题?只有弄清楚了适用的场景才能更深入地理解在什么地方可以用,以及怎么去用。

读完那20个例子,我发现有如下几点收获,分享给大家:

1、可以方便地用来运行异步程序

之前想要用Java来异步运行程序主要有两种方式:1)单独创建一个线程,执行start方法,或者2)创建一个executor线程池,然后提交任务到其中,相对来讲都比较麻烦,在一段业务逻辑代码里,需要插入创建线程或者线程池的语句,感觉不能“很自然”地引入异步处理。现在则可以使用CompletableFuture来方便地运行异步任务,例如:

CompletableFuture cf = CompletableFuture.runAsync(()->

    assertTrue(Thread.currentThread().isDaemon());

    randomSleep();

});

assertFalse(cf.isDone());

sleepEnough();

assertTrue(cf.isDone());

以Async结尾的方法会异步执行,其本质还是交给ForkJoinPool来异步执行。

2、串行执行一系列操作

在前一个阶段stage执行的方法结束之后,可以调用thenApply继续做操作,then意味着后面的动作在前面的动作结束之后运行,如果需要异步执行,选择带有async的方法thenApplyAsync。

CompletableFuture类实现了两个接口,Future 和 CompletionStage,CompletionStage是整个操作流程中的一个阶段stage,每个阶段stage完成后返回另一个stage,这样操作就可以串起来了。如果方法名字带有accept,则参数需要是实现Consumer接口的,可以是Consumer, BiConsumer;如果名字带有apply,则参数需要是实现Function接口的,可以是Function,BiFunction。

StringBuilderresult=newStringBuilder();

CompletableFuture.completedFuture("thenAccept message").thenAccept(s->result.append(s));

3、CompletableFuture执行异常结束

为了处理执行过程中的异常,可以给stage安排一个exception handler,也可以用异常来结束一个正在执行的stage,如下:

CompletableFuture cf = CompletableFuture.completedFuture("message").thenApplyAsync(String::toUpperCase,

        CompletableFuture.delayedExecutor(1,TimeUnit.SECONDS));

CompletableFuture exceptionHandler = cf.handle((s,th)->{return(th!=null)?"message upon cancel":""; });

cf.completeExceptionally(newRuntimeException("completed exceptionally"));

assertTrue("Was not completed exceptionally",cf.isCompletedExceptionally());

try{

     cf.join();

    fail("Should have thrown an exception");

}catch(CompletionException ex) {// just for testing

    assertEquals("completed exceptionally",ex.getCause().getMessage());

}

assertEquals("message upon cancel",exceptionHandler.join());

completeExceptionally方法可以用一个异常结束cf,此时等在(join)方法上的代码会收到这个异常退出,如果给cf安排了一个exception handler,这个handler会得到执行,返回另一个字符串"message upon cancel"。


4、取消计算

通过cancel方法可以取消一个stage的运行,取消不是通过中断interrupt实现的,而是通过CancellationException,cancel()的效果跟completeExceptionally(new CancellationException())是等价的。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 2018年4月17日, 星期二 早上, 小恩不知为什么, 开始哇哇大哭, 而且没完没了...... 我们赶紧检查各...
    少儿代码俱乐部阅读 160评论 0赞 1
  • 2017年3月6日 你喝酒了,跟几个朋友 可能是喝醉了,深夜打电话叫我给你开门 回来一通说,要尽最大努力给我幸福的...
    北北记生活阅读 316评论 0赞 0
  • 文末附千聊直播分享报名方式 我们都会遇到过这样的状况:1.做了一份完美的促销计划,活动时却没人参与;2.写了一段美...
    大辉船长阅读 534评论 0赞 2
  • 2017.1.19 今天在“姥姥家手擀面”吃了一份鸡腿面,这是我第一次在外面吃鸡腿面,因为在我印象中外面的鸡腿面肯...
    碳哥哥阅读 400评论 0赞 15

友情链接更多精彩内容