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 ...
随机推荐
- Eclipse 中svn 分支,主干 合并与同步:
Eclipse 中svn的合并与同步: 1. 从主干拉取到分支: 然后一直下一步,到完成就OK了. 2. 从分支代码合并到主干: 2.1.先将本地需要提交更新的代码提交更新到svn分支去 2.2. ...
- GitHub开源:升讯威ADO.NET增强组件 sheng.ADO.NET.Plus V1.3
GitHub: https://github.com/iccb1013/sheng.ADO.NET.Plus 早前分享过,当时没有把代码上传到Github,只是通过邮件的形式分享给了部分需要的朋友,最 ...
- xgboost-python参数深入理解
由于在工作中应用到xgboost做特征训练预测,因此需要深入理解xgboost训练过程中的参数的意思和影响. 通过search,https://www.analyticsvidhya.com/blog ...
- MyBatis解决字段名与实体类属性名不相同的冲突(四)
一.创建表和表数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no ), order_price FLOA ...
- PRINCE2的好处是什么?使用PRINCE2受益非浅
项目管理促进了全球许多公共部门与私营企业的经济活动. 优秀的项目管理意味着使用更少的资源在更短的时间内达到一个成功的结果,经过良好培训的项目经理能够帮助组织更加富有创新力,取得成功. 对那些希望展现自 ...
- JAVA循环依赖
最近看到一个问题:如果有两个类A和B,A类中有一个B的对象b,B类中有一个A的对象a,那么如何解决这两个类的相互依赖关系呢? 示例代码1 public class Test{ public stati ...
- 性能测试培训:帮你定位 Linux 性能问题的 18 个命令以及工具
性能测试培训:帮你定位 Linux 性能问题的 18 个命令以及工具 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在popte ...
- First Article
Hello World 愚人节的这天,我在我师傅的引导下,踏上了博客园这条不归路...... 先做下自我介绍,我姓李,木子李,因为本人比较中二,所以大家就叫我李中二吧! 工作是前端开发,目前正在深圳一 ...
- coolpad 5879logcat不能输入日志解决办法
有几天没完手机了,玩一下,发现不能打印日志了,记得最开始的时候 会弹出一个选项选择是否输出日志,在网上找了好的方法. 1.重启adb,点击DBMS 进行刷新. 2重启eclipse. 3.重装驱动. ...
- 【转】DHCP的请求过程
首先你得清楚DHCP的请求过程:1.client向server发送请求,发向广播地址2.server向client回应一个IP,发向单播地址3.client向server回应一个确认,发向广播地址,表 ...