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】的更多相关文章

  1. java并发:获取线程执行结果(Callable、Future、FutureTask)

    初识Callable and Future 在编码时,我们可以通过继承Thread或是实现Runnable接口来创建线程,但是这两种方式都存在一个缺陷:在执行完任务之后无法获取执行结果.如果需要获取执 ...

  2. Java程序员必须掌握的线程知识-Callable和Future

    Callable和Future出现的原因 创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需 ...

  3. 使用 DJ Java Decompiler 将整个jar包反编译成源文件

    使用 DJ Java Decompiler 将整个jar包反编译成源文件 所使用的软件是 DJ Java Decompiler 3.9. 下面是一个有用的参考文档,说明如何批量编译 http://ww ...

  4. 分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map

    原文:分享非常有用的Java程序 (关键代码)(五)---把 Array 转换成 Map import java.util.Map; import org.apache.commons.lang.Ar ...

  5. 用java将简单的word文档换成pdf文档

    用java将简单的word文档换成pdf文档的方式很多,因为很多都没有实际测试过,所以这里就先泛泛的说一下 整体上来看分两种: 1.纯java代码实现,有很多优秀的开源软件可以用,比如poi,itex ...

  6. 老杜告诉你java小白到大神是怎么炼成的(转载)

    老杜告诉你java小白到大神是怎么炼成的 1. 学习前的准备 一个好的学习方法(应该怎么学习更高效): 一个合格的程序员应该具备两个能力 有一个很好的指法速度(敲代码快) 有一个很好的编程思想(编程思 ...

  7. Java多线程系列--“JUC线程池”06之 Callable和Future

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  8. Java:多线程,线程池,使用CompletionService通过Future来处理Callable的返回结果

    1. 背景 在Java5的多线程中,可以使用Callable接口来实现具有返回值的线程.使用线程池的submit方法提交Callable任务,利用submit方法返回的Future存根,调用此存根的g ...

  9. java多线程之创建线程的4种方式及Future

    Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.Java可以用四种方式来创建线程: 继承Thread创建线程 实现Runnable接口创建线程 实现callab ...

随机推荐

  1. Jdom读取XML文件

    学习Spring时,我们经常看到很多xml配置文件,Spring通过在配置文件中的配置,使用IOC(控制反转),从而实现代码的灵活性,本篇我就为大家介绍一种解析xml方式--Jdom 首先我们到Jdo ...

  2. 适用MySQL Migration Toolkit 1.0 将oracle迁移到mysql中遇到的问题

    这里主要说一下我在适用中碰到的问题,主要过程参考 http://www.cnblogs.com/duwenlei/p/3520759.html. 首先启动MySQLMigrationTool.exe ...

  3. Unity 3D Framework Designing(2)——使用中介者模式解耦ViewModel之间通信

    当你开发一个客户端应用程序的时候,往往一个单页会包含很多子模块,在不同的平台下,这些子模块又被叫成子View(视图),或者子Component(组件).越是复杂的页面,被切割出来的子模块就越多,子模块 ...

  4. (转)Zabbix Agent-Windows平台配置指导

      原地址:http://blog.itpub.net/26739940/viewspace-1169538/   zabbix是一个CS结构的监控系统,支持ping,snmp等很多的监控,但是大部分 ...

  5. Chrome 33+ 自建 扩展 实现 custom.css

    http://bbs.kafan.cn/thread-1674386-1-2.html

  6. 性能测试分享:Jmeter的api监控工具解决方案

    性能测试分享:Jmeter的api监控工具解决方案 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询q ...

  7. CF #401 (Div. 2) E. Hanoi Factory (栈+贪心)

    题意:给你一堆汉诺塔的盘子,设内半径为a,设外半径为b,高度为h,如果bj ≤ bi 同时bj > ai 我们就认为i盘子能落在在j盘子上,问你最高能落多高 思路:一看题意我们就能想到贪心,首先 ...

  8. python作业设计:输入用户名密码,认证成功后显示欢迎信息,输错三次后锁定

    作业需求: 1.输入用户名密码 2.认证成功后显示欢迎信息 3.输错三次后锁定实现思路: 1.判断用户是否在黑名单,如果在黑名单提示账号锁定. 2.判断用户是否存在,如果不存在提示账号不存在. 3.判 ...

  9. JS常用特效方法总结

    1.按Ctrl提交 <body onkeydown="if(event.ctrlKey&&event.keyCode=='13') form1.submit.click ...

  10. ThreadLocal学习笔记

    首先,ThreadLocal是Java语言提供的用于支持线程局部变量的标准实现类.很多时候,ThreadLocal与Synchronized在功能上有一定的共性,都可以用来解决多线程环境下线程安全问题 ...