completablefuture基础知识概览

109 阅读2分钟

一、线程池

核心参数

  • corePoolSize 核心线程池大小
  • maximumPoolSize 线程池能创建线程的最大数量
  • keepAliveTime 空闲线程存活时间
  • workQueue 阻塞队列
  • handler 饱和策略

execute方法提交任务后,执行逻辑

  • 小于核心线程数,创建新线程
  • 阻塞队列未满,入队
  • 线程池未满,创建
  • 按饱和策略处理

二、对比Future

特点

  • 支持回调通知
    • Future需不断轮询判断任务是否结束
  • 便于将不同异步操作组合
    • Future编排回调存在回调地狱问题

三、简单使用

3.1 创建

通过静态方法创建实例

  • runAsync 无返回值
  • supplyAsync 有返回值
CompletableFuture.runAsync(Runnable);
CompletableFuture.runAsync(Runnable, Executor);

CompletableFuture.supplyAsync(Supplier<U>);
CompletableFuture.supplyAsync(Supplier<U>, Executor);

3.2 依赖单个任务

3.2.1 顺序执行
  • thenRun 无入参,无返回值
  • thenAccept 有入参,无返回值
  • thenApply 有入参,有返回值
CompletableFuture.supplyAsync(() -> "request").thenRun(() -> {});
CompletableFuture.supplyAsync(() -> "request").thenAccept(request -> {});
CompletableFuture.supplyAsync(() -> "request").thenRun(request -> "print --> " + request);
3.2.2 异常处理

两种方式 exceptionally 和 handle

3.3 依赖多个任务

3.3.1 and
  • thenAfterBoth 无入参,无返回
  • thenAcceptBoth 有入参,无返回
  • thenCombine 有入参,有返回
cfA.runAfterBoth(cfB, () -> {});
cfA.tehnAcceptBoth(cfB, (A, B) -> {});
cfA.tehnAcceptBoth(cfB, (A, B) -> A + B);

静态方法 allOf 等待多个任务都完成,无返回值

CompletableFuture.allOf(cfA, cfB, cfC)
3.3.2 or
  • runAfterEither 无入参,无返回
  • acceptEither 有入参,无返回
  • applyToEither 有入参,有返回
cfA.runAfterEither(cfB, () -> {});
cfA.tehnAcceptEither(cfB, req -> {});
cfA.tehnAcceptEither(cfB, req -> "req: " + req);

静态方法 anyOf 等待任一任务完成,返回类型为Object

CompletableFuture.anyOf(cfA, cfB, cfC)

四、基本原理

CompletableFuture 有两个核心字段

  • result 存当前CompletableFuture的结果
  • Completion 存依赖动作

不同CompletableFuture 如何编排起来?

  • CompletableFuture 为 被观察者,Completion为 观察者
  • 当CompletableFuture完成后,通过postComplete方法通知Completion
  • 形象上讲,这种机制 在 不同CompletableFuture节点 间 添加了 边

五、注意事项

5.1 有无Async后缀

不带Async后缀的方法

  • 如果注册时被依赖的操作已经执行完成,则由当前线程执行
  • 如果注册时被依赖的操作还未执行完,则由回调线程执行

带Async后缀的方法

  • 运行在指定线程池Executor
  • 当不传递Executor时,会使用ForkJoinPool中的共用线程池CommonPool

5.2 thenCompose

和thenCombine对比

  • 都是聚合任务
  • combine聚合结果,compose把多个cf实例组合成一个整体

和thenApply对比

  • thenApply接收的函数返回一个具体的值,thenCompose接收的函数返回一个新的cf实例
  • thenApply是同步,thenCompose是异步

参考资料

[1] CompletableFuture使用介绍

[2] CompletableFuture原理与实践