CompetableFutrue

Futrue

Futrue接口定义了(FutrueTask)定义了操作异步任务执行一些方法,如获取异步任务的执行结果、取消任务的执行、判断任务是否取消、判断任务执行是否完毕等。

Future 类是异步思想的典型运用,主要用在一些需要执行耗时任务的场景,避免程序一直原地等待耗时任务执行完成,执行效率太低。具体来说是这样的:当我们执行某一耗时的任务时,可以将这个耗时任务交给一个子线程去异步执行,同时我们可以干点其他事情,不用傻傻等待耗时任务执行完成。等我们的事情干完后,我们再通过 Future 类获取到耗时任务的执行结果。这样一来,程序的执行效率就明显提高了。

这其实就是多线程中经典的 Future 模式,你可以将其看作是一种设计模式,核心思想是异步调用,主要用在多线程领域,并非 Java 语言独有。

在 Java 中,Future 类只是一个泛型接口,位于 java.util.concurrent 包下,其中定义了 5 个方法,主要包括下面这 4 个功能:

  • 取消任务;
  • 判断任务是否被取消;
  • 判断任务是否已经执行完成;
  • 获取任务执行结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// V 代表了Future执行的任务返回值的类型
public interface Future<V> {
// 取消任务执行
// 成功取消返回 true,否则返回 false
boolean cancel(boolean mayInterruptIfRunning);
// 判断任务是否被取消
boolean isCancelled();
// 判断任务是否已经执行完成
boolean isDone();
// 获取任务执行结果
V get() throws InterruptedException, ExecutionException;
// 指定时间内没有返回计算结果就抛出 TimeOutException 异常
V get(long timeout, TimeUnit unit)

throws InterruptedException, ExecutionException, TimeoutExceptio

}

简单理解就是:我有一个任务,提交给了 Future 来处理。任务执行期间我自己可以去做任何想做的事情。并且,在这期间我还可以取消任务以及获取任务的执行状态。一段时间之后,我就可以 Future 那里直接取出任务执行结果

实例:

优点:

Futrue+线程池异步多线程任务配合,能够显著提高程序的执行效率。

缺点1

一旦调用get()方法求结果,如果计算没有完成容易导致程序阻塞

缺点2

轮询的方式会耗费无谓的CPU资源,而且也不见得能及时地得到计算结果.如果想要异步获取结果,通常都会以轮询的方式去获取结果

结论

Future对于结果的获取不是很友好,只能通过阻塞或轮询的方式得到任务的结果

CompetableFuture

get()方法在Future计算完成之前会一直处在阻塞状态下,isDone()方法容易耗费CPU资源,对于真正的异步处理我们希望是可以通过传入回调函数,在Future结束时自动调用该回调函数,这样,我们就不用等待结果。

阻塞的方式和异步编程的设计理念相违背,而轮询的方式会耗费无谓的CPU资源。因此,JDK8设计出CompletableFuture。

CompletableFuture提供了一种观察者模式类似的机制,可以让任务执行完成后通知监听的一方。

CompletionStage 接口描述了一个异步计算的阶段。很多计算可以分成多个阶段或步骤,此时可以通过它将所有步骤组合起来,形成异步计算的流水线。

CompletionStage 接口中的方法比较多,CompletableFuture 的函数式能力就是这个接口赋予的。从这个接口的方法参数你就可以发现其大量使用了 Java8 引入的函数式编程。

使用

无返回值的

默认有线程池(ForkJoinPool),上面这个是自己new的

有返回值的

跟Futrue区别

函数式接口


CompetableFutrue
http://example.com/2023/07/22/CompetableFuture/
Author
Posted on
July 22, 2023
Licensed under