@@ -468,6 +468,99 @@ CPU 密集型简单理解就是利用 CPU 计算能力的任务比如你在内
468468- ** [ Hippo-4] ( https://github.com/opengoofy/hippo4j ) ** :一款强大的动态线程池框架,解决了传统线程池使用存在的一些痛点比如线程池参数没办法动态修改、不支持运行时变量的传递、无法执行优雅关闭。除了支持动态修改线程池参数、线程池任务传递上下文,还支持通知报警、运行监控等开箱即用的功能。
469469- ** [ Dynamic TP] ( https://github.com/dromara/dynamic-tp ) ** :轻量级动态线程池,内置监控告警功能,集成三方中间件线程池管理,基于主流配置中心(已支持Nacos、Apollo,Zookeeper、Consul、Etcd,可通过SPI自定义实现)。
470470
471+ ## Future
472+ 473+ ### Future 类有什么用?
474+ 475+ ` Future ` 类是异步思想的典型运用,主要用在一些需要执行耗时任务的场景,避免程序一直原地等待耗时任务执行完成,执行效率太低。具体来说是这样的:当我们执行某一耗时的任务时,可以将这个耗时任务交给一个子线程去异步执行,同时我们可以干点其他事情,不用傻傻等待耗时任务执行完成。等我们的事情干完后,我们再通过 ` Future ` 类获取到耗时任务的执行结果。这样一来,程序的执行效率就明显提高了。
476+ 477+ 这其实就是多线程中经典的 ** Future 模式** ,你可以将其看作是一种设计模式,核心思想是异步调用,主要用在多线程领域,并非 Java 语言独有。
478+ 479+ 在 Java 中,` Future ` 类只是一个泛型接口,位于 ` java.util.concurrent ` 包下,其中定义了 5 个方法,主要包括下面这 4 个功能:
480+ 481+ - 取消任务;
482+ - 判断任务是否被取消;
483+ - 判断任务是否已经执行完成;
484+ - 获取任务执行结果。
485+ 486+ ``` java
487+ // V 代表了Future执行的任务返回值的类型
488+ public interface Future <V> {
489+ // 取消任务执行
490+ // 成功取消返回 true,否则返回 false
491+ boolean cancel (boolean mayInterruptIfRunning );
492+ // 判断任务是否被取消
493+ boolean isCancelled ();
494+ // 判断任务是否已经执行完成
495+ boolean isDone ();
496+ // 获取任务执行结果
497+ V get () throws InterruptedException , ExecutionException ;
498+ // 指定时间内没有返回计算结果就抛出 TimeOutException 异常
499+ V get (long timeout , TimeUnit unit )
500+ 501+ throws InterruptedException , ExecutionException , TimeoutExceptio
502+ 503+ }
504+ ```
505+ 506+ 简单理解就是:我有一个任务,提交给了 `Future ` 来处理。任务执行期间我自己可以去做任何想做的事情。并且,在这期间我还可以取消任务以及获取任务的执行状态。一段时间之后,我就可以 `Future ` 那里直接取出任务执行结果。
507+ 508+ ### Callable 和 Future 有什么关系?
509+ 510+ 我们可以通过 `FutureTask ` 来理解 `Callable ` 和 `Future ` 之间的关系。
511+ 512+ `FutureTask ` 提供了 `Future ` 接口的基本实现,常用来封装 `Callable ` 和 `Runnable `,具有取消任务、查看任务是否执行完成以及获取任务执行结果的方法。`ExecutorService .submit()` 方法返回的其实就是 `Future ` 的实现类 `FutureTask ` 。
513+ 514+ ```java
515+ <T > Future<T > submit(Callable<T > task);
516+ Future<?> submit (Runnable task );
517+ ```
518+ 519+ `FutureTask ` 不光实现了 `Future `接口,还实现了`Runnable ` 接口,因此可以作为任务直接被线程执行。
520+ 521+ ! [](https: // guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/concurrent/completablefuture-class-diagram.jpg)
522+ 523+ `FutureTask ` 有两个构造函数,可传入 `Callable ` 或者 `Runnable ` 对象。实际上,传入 `Runnable ` 对象也会在方法内部转换为`Callable ` 对象。
524+ 525+ ```java
526+ public FutureTask(Callable<V > callable) {
527+ if (callable == null )
528+ throw new NullPointerException ();
529+ this . callable = callable;
530+ this . state = NEW ;
531+ }
532+ public FutureTask(Runnable runnable, V result) {
533+ // 通过适配器RunnableAdapter来将Runnable对象runnable转换成Callable对象
534+ this . callable = Executors . callable(runnable, result);
535+ this . state = NEW ;
536+ }
537+ ```
538+ 539+ `FutureTask `相当于对`Callable ` 进行了封装,管理着任务执行的情况,存储了 `Callable ` 的 `call` 方法的任务执行结果。
540+ 541+ ### CompletableFuture 类有什么用?
542+ 543+ `Future ` 在实际使用过程中存在一些局限性比如不支持异步任务的编排组合、获取计算结果的 `get()` 方法为阻塞调用。
544+ 545+ Java 8 才被引入`CompletableFuture ` 类可以解决`Future ` 的这些缺陷。`CompletableFuture ` 除了提供了更为好用和强大的 `Future ` 特性之外,还提供了函数式编程、异步任务编排组合(可以将多个异步任务串联起来,组成一个完整的链式调用)等能力。
546+ 547+ 下面我们来简单看看 `CompletableFuture ` 类的定义。
548+ 549+ ```java
550+ public class CompletableFuture <T> implements Future<T > , CompletionStage<T > {
551+ }
552+ ```
553+ 554+ 可以看到,`CompletableFuture ` 同时实现了 `Future ` 和 `CompletionStage ` 接口。
555+ 556+ ! [](https: // guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/concurrent/completablefuture-class-diagram.jpg)
557+ 558+ `CompletionStage ` 接口描述了一个异步计算的阶段。很多计算可以分成多个阶段或步骤,此时可以通过它将所有步骤组合起来,形成异步计算的流水线。
559+ 560+ `CompletionStage ` 接口中的方法比较多,`CompletableFuture ` 的函数式能力就是这个接口赋予的。从这个接口的方法参数你就可以发现其大量使用了 Java8 引入的函数式编程。
561+ 562+ ! [](https: // guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/image-20210902093026059.png)
563+ 471564## AQS
472565
473566### AQS 是什么?
@@ -842,5 +935,6 @@ public int await() throws InterruptedException, BrokenBarrierException {
842935- 《实战 Java 高并发程序设计》
843936- 带你了解下 SynchronousQueue (并发队列专题):https: // juejin.cn/post/7031196740128768037
844937- 阻塞队列 — DelayedWorkQueue 源码分析:https: // zhuanlan.zhihu.com/p/310621485
938+ - Java 多线程(三)——FutureTask / CompletableFuture :https: // www.cnblogs.com/iwehdio/p/14285282.html
845939- Java 并发之 AQS 详解:https: // www.cnblogs.com/waterystone/p/4920797.html
846940- Java 并发包基石- AQS 详解:https: // www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html
0 commit comments