译文:http://www.importnew.com/16149.htmlhtml
原文:http://www.javacodegeeks.com/2014/12/asynchronous-timeouts-with-completablefuture.htmljava
CompletableFuture
Future.get()
方法会阻塞线程,一直阻塞,直到其所对应的任务完成或由于异常退出。在不恰当的地方调用此方法会由于线程阻塞而下降系统响应度。就像文中提到的。Future.get(long, TimeUnit)
能够必定的时间内超时退出,而不会像前一个方法那样一直阻塞线程。可是这对系统响应性的改进是治标不治本。CompletableFuture
,可用经过 CompletableFuture<Void> thenAccept(Consumer<? super T> action)
方法异步触发 send(Response)
方法。这时 serve()
方法会很快结束。而当 responseFuture
所对应的任务完成时,send(Response)
方法便会被调用,其执行线程同 responseFuture
所对应的任务的执行线程相同。responseFuture
所对应任务 (Runnable
or Callable
) 里面调用 send(Response)
方法。各类在实际工做中可能会遇到的问题暂且不说。只说两点:
responseFuture
所对应任务是不可修改的,好比调用自第三方模块responseFuture
所对应的任务中去调用 send(Response)
方法代表的含义是后者的功能从属于前者。这可能从业务角度上看是不合理的。即在本例中,responseFuture
所对应的任务和 send(Response)
方法在业务角度讲是属于同一级的。违反这一点会对代码可读性和可维护性不利。thenAccept
和 thenAcceptAsync
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
有两个和异常处理相关的方法,分别是 setDefaultUncaughtExceptionHandler
和 setUncaughtExceptionHandler
。前者是静态方法。这两个方法是用来设置异常处理策略的。固然,一个更简单的方法是在 send
里捕获和处理全部异常。若是你和你的公司容许大量无聊的重复代码出现的话,这么作是没有问题的。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
是一个提供了多种复杂异步功能的类。有时间最好能了解一下这个类的源代码编程