Future、CompletableFuture概述

简介: Future、CompletableFuture概述

1.同步和异步

(1)同步:需要等待结果返回,才能继续运行

(2)异步:不需要等待结果返回,就能继续运行

(3)异步设计:多线程可以让方法执行变为异步(比如在项目中,视频文件需要格式转换格式等操作比较费时时,这时开一个新线程处理视频转换,避免阻塞主线程)

2.Future接口

(1)Future接口定义了操作异步任务执行的一些方法,如获取异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕等。比如主线程让一个子线程去执行任务,子线程可能比较耗时,启动子线程开始执行任务后,主线程就去做其他事情了,忙其他事情或者先执行完,过了一会才去获取子任务的执行结果或变更的任务状态。

(2)Future是Java5新加的一个接口,它提供了一种异步并行计算的功能。如果主线程需要执行一个很耗时的计算任务,我们就可以通过Future把这个任务放到异步线程中执行。主线程继续处理其他任务或者先行结束,再通过Future获取计算结果。

(3)future+线程池异步多线程任务配合,能显著提高程序的执行效率

2.1 Future 的常用方法如下

(1)boolean cancel(boolean mayInterruptIfRunning)

试图取消对此任务的执行。如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。当调用 cancel 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程。

①参数:

mayInterruptIfRunning - 如果应该中断执行此任务的线程,则为 true;允许正在运行的任务运行完成, 则为false

②返回:

如果无法取消任务,则返回 false,这通常是由于它已经正常完成;否则返回 true

(2)V get() 如有必要,等待计算完成,然后获取其结果。

(3)V get(long timeout, TimeUnit unit)

如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。

(4)boolean isCancelled()

如果在任务正常完成前将其取消,则返回 true。

(5)boolean isDone()

如果任务已完成,则返回 true。

代码演示:
public class FutureDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
//      1.获取线程池对象
        ExecutorService es = Executors.newCachedThreadPool();
//      2.创建Callable类型的任务对象
        Future<Integer> f = es.submit(new MyCall(1, 1));
//      3.判断任务是否已经完成
        boolean done = f.isDone();
        System.out.println("判断任务是否完成"+done);
//        4.任务执行的结果
        Integer v = f.get();
        System.out.println("任务执行的结果是"+v);
//        5.判断取消任务的结果
        boolean b = f.cancel(true);
        System.out.println("取消任务执行的结果"+b);
    } }
class MyCall implements Callable<Integer> {
    private int a;
    private int b;
    public MyCall(int a, int b) {
        this.a = a;
        this.b = b;}
    @Override
    public Integer call() throws Exception {
        String name = Thread.currentThread().getName();
        System.out.println(name + "准备开始计算...");
        Thread.sleep(2000);
        System.out.println("计算完成...");
        return a + b;
    } }

2.2 Future编码实战和优缺点分析

(1)优点:Future+线程池异步多线程任务配合,能显著提高程序的运行效率。

(2)缺点:

①get()阻塞:一旦调用get()方法求结果,不管你是否计算完成,非要等到结果才会离开,如果没有计算完成容易程序堵塞。

②isDone()轮询:轮询的方式会耗费无谓的cpu资源,而且也不见得能及时得到计算结果,如果想要异步获取结果,通常会以轮询的方式去获取结果,尽量不要阻塞。

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

3.CompletableFuture

3.1 CompletableFuture为什么会出现

(1)get()方法在Future计算完成之前会一直处在阻塞状态下,阻塞的方式和异步编程的设计理念相违背;而isDone()轮询的方式会消耗无谓的CPU资源,而且也不见的能及时地得到计算结果。对于真正的异步处理我们希望是可以通过传入回调参数,在future结束时自动调用该回调函数,这样我们就不用等待结果。因此,JDK8设计出了CompletableFuture

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

3.2 CompletionStage

public class CompletableFuture<T> implements Future<T>, CompletionStage<T> 

(1)CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段。一个阶段的计算执行可以是一个Function,Consumer或者Runnable。

(2)一个阶段的执行可能是被单个阶段的完成触发,也可能是由多个阶段一起触发

3.3 CompletableFuture四大静态方法

(1) runAsync无返回值

①返回一个新的CompletableFuture,它在运行给定操作后由运行在 ForkJoinPool.commonPool()中的任务 异步完成。

public static CompletableFuture<Void> runAsync(Runnable runnable)

②返回一个新的CompletableFuture,它在运行给定操作之后由在给定执行程序中运行的任务异步完成。

public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)

(2)supplyAsync有返回值

①返回一个新的CompletableFuture,它通过在 ForkJoinPool.commonPool()中运行的任务与通过调用给定的供应商获得的值 异步完成。

static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)

②返回一个新的CompletableFuture,由给定执行器中运行的任务异步完成,并通过调用给定的供应商获得的值。

static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 
目录
相关文章
|
2月前
|
Java
Java并发编程:理解并使用Future和Callable接口
【2月更文挑战第25天】 在Java中,多线程编程是一个重要的概念,它允许我们同时执行多个任务。然而,有时候我们需要等待一个或多个线程完成,然后才能继续执行其他任务。这就需要使用到Future和Callable接口。本文将深入探讨这两个接口的用法,以及它们如何帮助我们更好地管理多线程。
|
2月前
|
Java API
java多线程之FutureTask、Future、CompletableFuture
java多线程之FutureTask、Future、CompletableFuture
|
2月前
|
Java
深入理解 Java 异步编程:Future 和 CompletableFuture 的全面比较
深入理解 Java 异步编程:Future 和 CompletableFuture 的全面比较
78 0
|
8月前
|
Java
ExecutorService、Callable、Future实现有返回结果的多线程原理解析
ExecutorService、Callable、Future实现有返回结果的多线程原理解析
48 0
|
8月前
|
存储 Java
并发编程系列教程(09) - Callable与Future模式
并发编程系列教程(09) - Callable与Future模式
32 0
|
10月前
|
消息中间件 Java 中间件
Future and CompletableFuture
Future代表异步执行的结果,也就是说异步执行完毕后,结果保存在Future里, 我们在使用线程池submit()时需要传入Callable接口,线程池的返回值为一个Future,而Future则保存了执行的结果 ,可通过Future的get()方法取出结果,如果线程池使用的是execute(),则传入的是Runnable接口 无返回值。
42 0
|
10月前
|
Java 调度
并发编程——Future & CompletableFuture
Java创建线程的方式,一般常用的是Thread,Runnable。如果需要当前处理的任务有返回结果的话,需要使用Callable。Callable运行需要配合Future。
30 0
|
12月前
|
存储 Java
JUC基础(二)—— Future接口 及其实现
JUC基础(二)—— Future接口 及其实现
135 1
|
11月前
|
Java
【并发技术11】Callable与Future的应用
【并发技术11】Callable与Future的应用
|
Java API
Java并发编程-Future系列之Future的介绍和基本用法
Java并发编程-Future系列之Future的介绍和基本用法
168 0
Java并发编程-Future系列之Future的介绍和基本用法