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. 【SF】开源的.NET CORE 基础管理系统 -介绍篇

    [SF]开源的.NET CORE 基础管理系统 -系列导航 1.环境: .NET Core SDK (https://www.microsoft.com/net/core) SQL Server or ...

  2. macaca环境搭建(web 和 android)

    一.安装配置JDK 1.1下载JDK地址http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.h ...

  3. C++实现四叉树

    什么是四叉树? 四叉树可以有效解决这个问题. 四叉树每一层都把地图划分四块,根据地图尺寸来决定树的层数,层数越大划分越细. 但需要对某一范围的单位筛选时,只需要定位到与范围相交的树区域,再对其区域内的 ...

  4. 平时自己项目中用到的CSS

    outline  当选中input元素的时候会出现状态线, outline设置成none就没了 input{ outline:none; } contentditable  设置元素内的文本是否可编辑 ...

  5. 老李推荐:第8章3节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 3

    首先它通过查找JVM中的System Property来找到"com.android.monkeyrunner.bindir"这个属性的值,记得前面小节运行环境初始化的时候在mon ...

  6. webdriver介绍&与Selenium RC的比较

    什么是webdriver? webdriver是一个web自动化测试框架,不同于selenium IDE只能运行在firefox上,webdriver能够在不同的浏览器上执行你的web测试用例.其支持 ...

  7. CF #404 (Div. 2) D. Anton and School - 2 (数论+范德蒙恒等式)

    题意:给你一个由'('和')'组成的字符串,问你有多少个子串,前半部分是由'('组成后半部分由')'组成 思路:枚举这个字符串中的所有'('左括号,它左边的所有'('左括号的个数为num1,它的右边的 ...

  8. Hibernate(四)之对象状态及一级缓存

    一.Hibernate中的对象状态 1.1.瞬时态(临时态) 没有与Hibernate产生关联 与数据库中的记录没有产生关联(有关联就是与数据库中表的id相对应) 获得:一般都只直接创建(new) 瞬 ...

  9. 图的基本算法(BFS和DFS)(转载)

    图是一种灵活的数据结构,一般作为一种模型用来定义对象之间的关系或联系.对象由顶点(V)表示,而对象之间的关系或者关联则通过图的边(E)来表示. 图可以分为有向图和无向图,一般用G=(V,E)来表示图. ...

  10. WebService基础学习(二)—三要素

    一.Java中WebService规范      JAVA 中共有三种WebService 规范,分别是JAX-WS.JAX-RS.JAXM&SAAJ(废弃).   1.JAX-WS规范    ...