美文网首页
java 8引入的CompletableFuture的使用

java 8引入的CompletableFuture的使用

作者: 7mile | 来源:发表于2018-10-23 12:47 被阅读0次

       最近在学习如何使用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())是等价的。

相关文章

网友评论

      本文标题:java 8引入的CompletableFuture的使用

      本文链接:https://www.haomeiwen.com/subject/pvkdaftx.html