“用 CompletableFuture 处理异步超时” 阅读总结

译文:http://www.importnew.com/16149.html

原文:http://www.javacodegeeks.com/2014/12/asynchronous-timeouts-with-completablefuture.html

总结

为什么要引入 CompletableFuture

  • Future.get() 方法会阻塞线程,一直阻塞,直到其所对应的任务完成或因为异常退出。在不恰当的地方调用此方法会因为线程阻塞而降低系统响应度。就像文中提到的。
  • Future.get(long, TimeUnit) 可以一定的时间内超时退出,而不会像前一个方法那样一直阻塞线程。但是这对系统响应性的改进是治标不治本。
  • Java 8 引入了 CompletableFuture,可用通过 CompletableFuture<Void> thenAccept(Consumer<? super T> action) 方法异步触发 send(Response) 方法。这时 serve() 方法会很快结束。而当 responseFuture 所对应的任务完成时,send(Response) 方法便会被调用,其执行线程同 responseFuture 所对应的任务的执行线程相同。
  • 对于上一点,有人会问,何必这么麻烦?直接在 responseFuture 所对应任务 (Runnable or Callable) 里面调用 send(Response) 方法。各种在实际工作中可能会遇到的问题暂且不说。只说两点:
    1. responseFuture 所对应任务是不可修改的,比如调用自第三方模块
    2. 即便代码可修改,但在 responseFuture 所对应的任务中去调用 send(Response) 方法表明的含义是后者的功能从属于前者。这可能从业务角度上看是不合理的。即在本例中,responseFuture 所对应的任务和 send(Response) 方法在业务角度讲是属于同一级的。违反这一点会对代码可读性和可维护性不利。

thenAcceptthenAcceptAsync

  • thenAccept(Consumer<? super T> action) 这个方法的命名采用了类似 Promise 的命名风格。如果把这个方法命名为 addListener 会更容易理解,但是命名为 addListener 不能体现出 thenAccept 能返回 CompletableFuture 从而形成链式调用的特点。
  • CompletableFuture 还有一个方法 thenAcceptAsync(Consumer<? super T> action, Executor executor),可以为任务指定线程池,从而隔离不同任务的执行线程,避免相互影响。(吐槽一下,CompletableFuture 定义的方法实在太多了)

异常处理

  • 再使用 thenAccept 方法调用 send 方法实现了异步编程,带来了好处,但同时也带来了很多问题。第一个问题便是异常的处理。在使用 Java 写并发程序的时候要注意异常处理,这是一个从 Java 1.4 开始就需要注意的问题。有经验的开发人员都知道 Java 的 Thread 有两个和异常处理相关的方法,分别是 setDefaultUncaughtExceptionHandlersetUncaughtExceptionHandler。前者是静态方法。这两个方法是用来设置异常处理策略的。当然,一个更简单的方法是在 send 里捕获和处理所有异常。如果你和你的公司允许大量无聊的重复代码出现的话,这么做是没有问题的。
  • 从 Java 8 开始,在并发编程中处理异常,除了上面提到的自己写 try catch 和使用 UncaughtExceptionHandler 这两种方法外,对于本例来说,还可以通过 CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn) 方法来处理异常。
  • exceptionally() 方法中的 Function 是用来处理 responseFuture 所对应任务抛出的异常
  • 如果出现异常,Function 的返回值将作为 thenAccept 方法的 Consumer 入参。在本例中就是 null

超时异常

  • 解决了异常问题之后另一个需要解决的问题是如何实现超时异常
  • 通过 CompletableFuture 实现超时异常场景的方法是通过使用 CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)。这个方法的意思是 this CompletionStage 或 other CompletionStage 谁先完成,其结果就会作为 Consumer<? super T> action 的入参。然后通过实现一个超时的 CompletionStage
  • 接下来就是对代码可读性的一些改进,用了 CompletableFuture 另一些方法。

最后

CompletableFuture 是一个提供了多种复杂异步功能的类。有时间最好能了解一下这个类的源代码

转载于:https://my.oschina.net/lifany/blog/515572

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值