Transform java future into completable future 【将 future 转成 completable future】
Future is introduced in JDK 1.5 by Doug Lea to represent "the result of an asynchronous computation".
Java 5中引入了Future接口,用于代表异步计算的结果
ExecutorService exe = Executors.newCachedThreadPool();
Runnable runnable = () -> System.out.println("Runnable");
Callable<String> callable = () -> "Callable";
exe.submit(runnable);
Future<String> futureResult = exe.submit(callable);
String result = futureResult.get();
System.out.println(result);
exe.shutdown();
Similar to runnable, callable can also be submitted to executor service. Differently, callable is "A task that returns a result and may throw an exception."
The call to get a future result lead current thread to wait "if necessary for the computation to complete, and then retrieves its result." Below is one implementation of get method.
同时还引入了Callable接口来代表有返回值的任务,把 callable提交给线程池便可以获得一个future。
当我们想要获取callable的结果,或者说想要拿到future的值,可能会需要适时的等待。参照ForkjoinPool中对Future get的实现,基本可以明白,当前线程会一直等到future所代表的异步任务执行完毕。
public final V get() throws InterruptedException, ExecutionException {
int s = (Thread.currentThread() instanceof ForkJoinWorkerThread) ?
doJoin() : externalInterruptibleAwaitDone();
Throwable ex;
if ((s &= DONE_MASK) == CANCELLED)
throw new CancellationException();
if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
throw new ExecutionException(ex);
return getRawResult();
}
In JDK 1.8, another future, CompletableFuture, is introduced by the same author with epoch-making significance. Completable future is "A {@link Future} that may be explicitly completed (setting its value and status), and may be used as a {@link CompletionStage}, supporting dependent functions and actions that trigger upon its completion."
Java 8中,Doug Lea大神又引入了CompletableFuture 这一大作,既拥有future的特性,同时又可以根据任务的完成状态来触发后续的动作,以一种可同步可异步的调用链方式来执行更为复杂的任务。
Now it comes to the interesting part. Hey, what if we want to convert the legacy future into completable future so as to make full use of the new features?
Well, let's see a snippet from stack overflow http://stackoverflow.com/questions/23301598/transform-java-future-into-a-completablefuture
现在问题来了,假如我们想要把老代码中的 future 转换成 completable future,怎么做比较好呢?如果第三方库本身拥有完成和失败的回调,整合completable future 还相对容易,就像下面这个从stack overflow搬来的例子一样:
AsynchronousFileChannel open = AsynchronousFileChannel.open(Paths.get("/some/file"));
// ...
CompletableFuture<ByteBuffer> completableFuture = new CompletableFuture<ByteBuffer>();
open.read(buffer, position, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer result, Void attachment) {
completableFuture.complete(buffer);
}
@Override
public void failed(Throwable exc, Void attachment) {
completableFuture.completeExceptionally(exc);
}
});
completableFuture.thenApply(...)
If the 3rd party library support complete and fail callback, it's convinient to integrate with completable future. But usually, future inteferface won't contain these methods.
Hmmm, feels so close... and unreachable. Wait, how about ListenableFuture introduced by Guava ? It can add callbacks for a future.
然而。。。通常的future接口并没有这些方法╮( ̄▽ ̄")╭ 别急,俗话说,车到山前必有路,让我们回想回想Guava所引入的ListenableFuture, 它可以给future 增加完成和失败的回调。
ListeningExecutorService executor1 = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = executor1.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
}, executor2);
Pattern matched, problem solved, and everyone is happy now.
Do care about executor1 and executor2, configure the thread pools properly will boost app performance, cheers~
看到熟悉的模型,问题迎刃而解。
注意下上面例子中的executor1 和 executor2,实际运用的时候合理的调节线程池的参数可以更好的提升应用性能。
Transform java future into completable future 【将 future 转成 completable future】的更多相关文章
- java并发:获取线程执行结果(Callable、Future、FutureTask)
初识Callable and Future 在编码时,我们可以通过继承Thread或是实现Runnable接口来创建线程,但是这两种方式都存在一个缺陷:在执行完任务之后无法获取执行结果.如果需要获取执 ...
- Java程序员必须掌握的线程知识-Callable和Future
Callable和Future出现的原因 创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需 ...
- 使用 DJ Java Decompiler 将整个jar包反编译成源文件
使用 DJ Java Decompiler 将整个jar包反编译成源文件 所使用的软件是 DJ Java Decompiler 3.9. 下面是一个有用的参考文档,说明如何批量编译 http://ww ...
- 分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map
原文:分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map import java.util.Map; import org.apache.commons.lang.Ar ...
- 用java将简单的word文档换成pdf文档
用java将简单的word文档换成pdf文档的方式很多,因为很多都没有实际测试过,所以这里就先泛泛的说一下 整体上来看分两种: 1.纯java代码实现,有很多优秀的开源软件可以用,比如poi,itex ...
- 老杜告诉你java小白到大神是怎么炼成的(转载)
老杜告诉你java小白到大神是怎么炼成的 1. 学习前的准备 一个好的学习方法(应该怎么学习更高效): 一个合格的程序员应该具备两个能力 有一个很好的指法速度(敲代码快) 有一个很好的编程思想(编程思 ...
- Java多线程系列--“JUC线程池”06之 Callable和Future
概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...
- Java:多线程,线程池,使用CompletionService通过Future来处理Callable的返回结果
1. 背景 在Java5的多线程中,可以使用Callable接口来实现具有返回值的线程.使用线程池的submit方法提交Callable任务,利用submit方法返回的Future存根,调用此存根的g ...
- java多线程之创建线程的4种方式及Future
Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.Java可以用四种方式来创建线程: 继承Thread创建线程 实现Runnable接口创建线程 实现callab ...
随机推荐
- mysql语句sum求和为null的问题
select sum(price) as price from order where status='SUCCESS'; 如果price对应的所有的值为0,那么算出来的和为null: 可以采用ifn ...
- 一个web应用的诞生(8)--博文发布
这个系统一直号称轻博客,但貌似博客的功能还没有实现,这一章将简单的实现一个博客功能,首先,当然是为数据库创建一个博文表(models\post.py): from .. import db from ...
- Struts2之标签使用
上一篇我们一起探讨了Struts2中的OGNL表达式的知识,本篇我们一起来学习一下关于Struts2标签的使用,包括:基础标签:property.set.bean.include:判断标签:if el ...
- Android两种为ViewPager+Fragment添加Tab的方式
在Android开发中ViewPager的使用是非常广泛的,而它不仅仅能够实现简单的开始引导页,还可以结合Fragment并添加Tab作为选项卡或为显示大批量页面实现强大的顺畅滑动 下面介绍两种为Vi ...
- C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(下)
译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(下)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...
- 20. Valid Parentheses - 括号匹配验证
Description: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determin ...
- iOS中书写代码规范35条小建议
1.精简代码, 返回最后一句的值,这个方法有一个优点,所有的变量都在代码块中,也就是只在代码块的区域中有效,这意味着可以减少对其他作用域的命名污染.但缺点是可读性比较差 NSURL *url = ({ ...
- [SinGuLaRiTy] 平衡树
[SinGuLaRiTy-1009] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 二叉查找树 二叉查找树是指具有下列性质的非空二叉树: ⑴ ...
- Spring整合Struts2,Hibernate的xml方式
作为一个学习中的码农,一直学习才是我们的常态,所以最近学习了SSH(Spring,Struts2,Hibernate)整合,数据库用的MySQL. 写了一个简单的例子,用的工具是IntelliJ Id ...
- 老李推荐:第2章4节《MonkeyRunner源码剖析》了解你的测试对象: NotePad窗口Activity之菜单简介
老李推荐:第2章4节<MonkeyRunner源码剖析>了解你的测试对象: NotePad窗口Activity之菜单简介 NotePad窗口Activity之菜单简介 这里我们总共用到 ...