深入理解 Future, CompletableFuture, ListenableFuture,回调机制 ...

打印 上一主题 下一主题

主题 1003|帖子 1003|积分 3013

深入理解 Future, CompletableFuture, ListenableFuture,回调机制

本文禁止转载。
本文从设计思想、详细实现等角度分析了 Future、CompletableFuture、ListenableFuture等接口或类,提出了一些最佳实践,英华内容为示例代码。耐心看完,相信你一定会有所收获。文章首发公众号,欢迎关注。
理想的 Future


  • 函数式思想:值类型,和类型,结果延迟获取,最终状态有两种,正常获取结果 v 大概异常结果 ex。
  • 只有读逻辑,写逻辑由其他类实现(如 Scala 中的 Promise)
  • 支持回调,链式调用
  • 对异步支持良好,但是也支持同步调用
  • 可取消任务,取消的结果视为异常结果
现实的 Future 接口


  • Future 封装了任务(写逻辑),提供了阻塞 get()方法,但是结果为四种状态,而且是以受检异常形式抛出,每次处置处罚时都必要 try-catch,无法分别处置处罚。受检异常的题目是即使知道代码不会抛异常,还是要写模版代码 catch 处置处罚。
  1. V get() throws InterruptedException, ExecutionException;
  2. V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
复制代码

  • 非逼迫的取消任务机制,调用 cancel 方法,若任务处于 NEW 状态,可以保证取消;若任务处于运行状态,必要依赖于任务支持停止机制,Java 的停止机制是设立标志位,无法直接传输数据。
  1. boolean cancel(boolean mayInterruptIfRunning);
复制代码

  • Future 接口不支持回调以及链式调用,CompletableFuture 实现了此功能,但是自身也有一些题目。
  • Future 接口可以当做值类型利用,也推荐这么利用,不过许多情况下会出现对于 Future 结果的修改。note: Java 底层不支持值类型,其值类型官方说法为 value-based。必要注意区分值类型和可变数据容器 Wrapper 类,值类型是不可变的,比如 Integer 和 AtomicInteger 的区别。
  • JDK19 的改进
在 JDK19 终于提供了以下一系列方法,其基本思想就是值类型,绕过 get 阻塞调用的弊端。当已知结果已经得出后,直接取值,无需进行受检异常处置处罚。美中不足:停止机制还是不视为异常的一部门,exceptionNow 在停止状态时,还是会停止当前线程。
  1. default V resultNow();
  2. default Throwable exceptionNow();
  3. default State state();
  4. enum State {
  5.       /**
  6.        * The task has not completed.
  7.        */
  8.       RUNNING,
  9.       /**
  10.        * The task completed with a result.
  11.        * @see Future#resultNow()
  12.        */
  13.       SUCCESS,
  14.       /**
  15.        * The task completed with an exception.
  16.        * @see Future#exceptionNow()
  17.        */
  18.       FAILED,
  19.       /**
  20.        * The task was cancelled.
  21.        * @see #cancel(boolean)
  22.        */
  23.       CANCELLED
  24. }
复制代码
总之,新增的默认方法利用必要先进行状态判定,然后调用获取结果方法。以下是代码示例:
  1. // 处理已运算结果
  2. results = futures.stream()
  3.            .filter(f -> f.state() == Future.State.SUCCESS)
  4.            .map(Future::resultNow)
  5.            .toList();
  6. // allOf 运算结果处理
  7. CompletableFuture.allOf(c1, c2, c3).join();
  8. foo(c1.resultNow(), c2.resultNow(), c3.resultNow());
复制代码
不过,默认方法对于第三方库来说可能会出现运行题目,必要确认第三方库支持再利用默认方法。
CompletableFuture 大幅改进

岁月史书:Future, ExecutorService, BlockingQueue, AQS 等在 JDK1.5 推出,随后 Google Guava 类库提供了 ListenableFuture 补全了 Future 的回调功能,CompletableFuture 鉴戒了 ListenableFuture 功能,联合函数式支持,在 JDK1.8 推出。
1. 链式调用
  1. public class CompletableFuture<T> implements Future<T>, CompletionStage<T>
复制代码
大部门链式调用方法界说在 CompletionStage 中:
[table][tr]CompletionStage 接口方法函数式接口Stream 相似方法[/tr][tr][td]<U> CompletionStage<U> thenApply(Function
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表