CompletableFuture学习

本文介绍了Future接口的使用及其缺点,如get方法阻塞和isDone消耗CPU。然后重点讨论了Java8中的CompletableFuture,它提供了非阻塞获取结果和观察者模式,简化异步编程并支持回调和链式调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


学习内容

前言 :Future 接口 理论知识
定义了操作异步任务 执行一些方法, 比如获取异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕等。
栗子 : 主任务 主线程 不能中断开启一个子线程, 让子线程 去执行耗时的任务。

对应的API
在这里插入图片描述


public class Test4 {
    public static void main(String[] args) {

        try {
            MyThread2 t2 = new MyThread2();
            FutureTask futureTask = new FutureTask<>(t2);
            futureTask.get(); // 获取返回值    输出 this is call ()

            Thread thread = new Thread(futureTask);
            thread.start();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
/**
 *     Runnable 和 Callable 区别
 *     1. 方法 不同
 *     2. 返回值类型
 *     3.方法会抛出异常
 */
class MyThread2 implements Callable<String> {

    @Override
    public String call() throws Exception {
        return "this is call ()";
    }
}
class MyThread implements Runnable {

    @Override
    public void run() {

    }
}

缺点 :

  1. 使用 get 会阻塞 , 一旦调用get()方法求结果,如果计算机没有完成容易导致程序阻塞。
  2. isDone 不断轮询 使用 while(true) 会消耗cpu 效率
    结论:Future 获取结果不是很友好,只能通过阻塞或者轮询方法获取结果。

CompletableFuture在Future 上的改进:

前言: get()方法在Future 计算完成之前会一直处在阻塞状态下,isDone()方法容易耗费CPU资源,阻塞的方式和异步编程的设计理念相违背,而轮询的方式会耗费无谓的CPU资源。因此,JDK8设计出CompletableFuture。
CompletableFuture提供了一种观察者模式类似的机制,可以让任务执行完成后通知监听的一方。

是什么:

  1. 在Java8中,CompletableFuture提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合CompletableFuture 的方法。
  2. 它可能代表一个明确完成的Future,也有可能代表一个完成阶段(CompletionStage ),它支持在计算完成以后触发一些函数或执行某些动作。
  3. 它实现了Future和CompletionStaqe接口

public class CompletableFuture implements Future, CompletionStage {}

在这里插入图片描述

completionstage
completionstage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段
一个阶段的计算执行可以是一个function,consumer或者runable,比如:stage.thenapplyx>square()thenaccept
(x->system.out.print(x).thenrun(0)->system.out.println0)
.一个阶段的执行可能是被单个阶段的完成触发,也可能是由多个阶段一起触发
代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段,有些类似nx系统的管造分隔符传参数。


四个静态方法, 来创建一个异步任务

在这里插入图片描述

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
    100,
    200,
    1,
    TimeUnit.SECONDS,
    new LinkedBlockingDeque<>()
);

try {
    CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
        try {
            System.out.println(Thread.currentThread().getName() + ":come in ");
            Thread.sleep(100);
            int result = ThreadLocalRandom.current().nextInt(10);
            System.out.println("结果 :" + result);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello supplyAsync()";
        /**
         *
         * public CompletableFuture<T> whenComplete(
         * BiConsumer<? super T, ? super Throwable> action) {
         * return uniWhenCompleteStage(null, action);
         }     V 表示上一个步骤得出的结果   也就是 result
         e 表示 是否异常
         */
    }, threadPoolExecutor).whenComplete((v, e) -> {
        if (e == null) {
            System.out.println("finished");
        }
        /**
         *     public CompletableFuture<T> exceptionally(
         *         Function<Throwable, ? extends T> fn) {
         *         return uniExceptionallyStage(fn);
         *     }
         *     程序出现了异常 会走这个分支
         */
    }).exceptionally(e -> {
        e.printStackTrace();
        System.out.println("异常情况" + e.getCause() + "\t");
        return null;
    });

    System.out.println(Thread.currentThread().getName() + "主线程 ");
} catch (Exception e) {
    e.printStackTrace();
}finally {
    threadPoolExecutor.shutdown();
}

优点

  1. 异步任务结束时,会自动回调某个对象的方法:
  2. completablefuture的优点 主线程设置好回调后,不再关心异步任务的执行,异步任务之间可以顺序执行
  3. 异步任务出错时,会自动回调某个对象的方法:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值