JUC—CompletableFuture笔记

CompletableFuture笔记

      • 1. Future和Callable接口
      • 2. FutureTask
      • 3. 引出CompletableFuture
        • 3.1 CompletableFuture和CompletionStage 介绍
        • 3.2 核心的四个静态方法,来创建一个异步操作
          • 1) runAsync 无 返回值
          • 2) supplyAsync() 有 返回值
        • 3.3 案例精讲-从电商网站的比价需求说开去
        • 3.4 说说join和get对比
        • 3.5 大厂业务需求说明
        • 3.6 CompletableFuture常用方法
          • 1) 获得结果和触发计算
          • 2) 对计算结果进行处理
          • 3) 对计算结果进行消费
          • 4) 对计算速度进行选用
          • 5) 对计算结果进行合并

1. Future和Callable接口

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

Callable接口中定义了需要有返回的任务需要实现的方法。
JUC—CompletableFuture笔记_第1张图片

应用: 比如主线程让一个子线程去执行任务,子线程可能比较耗时,启动子线程开始执行任务后,主线程就去做其他事情了,过了一会才去获取子任务的执行结果。

2. FutureTask

本源的Future接口相关架构
JUC—CompletableFuture笔记_第2张图片
FutureTask 的使用

    FutureTask<Integer> futureTask = new FutureTask<>(() -> {
        System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
        try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}
        return 1024;
    });

    new Thread(futureTask, "t1").start();

	//1.不见不散(阻塞),只要出现get方法,不管是否计算完成都阻塞等待结果出来再运行
    // System.out.println(futureTask.get());

	//2.过时不候
    // System.out.println(futureTask.get(2L,TimeUnit.SECONDS));

    //3.不要阻塞,尽量用轮询替代
    while (true) {
        if (futureTask.isDone()) { // 判断是否完成
            System.out.println("----result: " + futureTask.get());
            break; //完成就break
        } else {
            System.out.println("还在计算中,别催,越催越慢,再催熄火");
        }
    }

FutureTask的缺点:

1. get()阻塞 : 一旦调用get()方法,不管是否计算完成都会导致阻塞。如果使用 futureTask.get() 最好放在最后

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

总结:不见不散futureTask.get() —> 过时不候futureTask.get(2L,TimeUnit.SECONDS) —> 轮询futureTask.isDone()

想完成一些复杂的任务

  1. 应对Future的完成时间,完成了可以告诉我,也就是我们的回调通知
  2. 将两个异步计算合成一个异步计算,这两个异步计算互相独立,同时第二个又依赖第一个的结果。
  3. 当Future集合中某个任务最快结束时,返回结果。
  4. 等待Future结合中的所有任务都完成。
  5. 。。。。。。

3. 引出CompletableFuture

3.1 CompletableFuture和CompletionStage 介绍

类架构说明
JUC—CompletableFuture笔记_第3张图片

接口CompletionStage

代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段,有些类似Linux系统的管道分隔符传参数。
JUC—CompletableFuture笔记_第4张图片
类CompletableFuture 可以完全替代FutureTask
JUC—CompletableFuture笔记_第5张图片

3.2 核心的四个静态方法,来创建一个异步操作
1) runAsync 无 返回值

JUC—CompletableFuture笔记_第6张图片
代码演示:
JUC—CompletableFuture笔记_第7张图片
结果:
JUC—CompletableFuture笔记_第8张图片

2) supplyAsync() 有 返回值

​ CompletableFuture supplyAsync(Supplier supplier)
JUC—CompletableFuture笔记_第9张图片
代码演示:
JUC—CompletableFuture笔记_第10张图片
结果:
JUC—CompletableFuture笔记_第11张图片


面试题:线程池用在什么地方?

上述方法的Executor executor参数说明

  • 没有指定Executor的方法,直接使用默认的ForkJoinPool.commonPool() 作为它的线程池执行异步代码。
  • 如果指定线程池,则使用我们自定义的或者特别指定的线程池执行异步代码

JUC—CompletableFuture笔记_第12张图片


CompletableFuture四个函数

使用:
JUC—CompletableFuture笔记_第13张图片
结果:
JUC—CompletableFuture笔记_第14张图片


CompletableFuture的优点

JUC—CompletableFuture笔记_第15张图片

3.3 案例精讲-从电商网站的比价需求说开去

函数式编程已经主流

​ Lambda +Stream+链式调用+Java8函数式编程带走
JUC—CompletableFuture笔记_第16张图片

3.4 说说join和get对比

​ join() = get() 都是获取结果 ,都会造成阻塞

​ get() 会抛出异常,join() 不抛出异常

如果有异常在此抛出
JUC—CompletableFuture笔记_第17张图片

3.5 大厂业务需求说明

功能→性能 (案例:比价需求)

3.6 CompletableFuture常用方法
1) 获得结果和触发计算

获取结果

​ public T join()

​ public T get() 不见不散

​ public T get(long timeout, TimeUnit unit) 过时不候

​ public T getNow(T valueIfAbsent) 没有计算完成的情况下,给我一个替代结果

立即获取结果不阻塞 计算完,返回计算完成后的结果, 没算完,返回设定的valueIfAbsent值
JUC—CompletableFuture笔记_第18张图片JUC—CompletableFuture笔记_第19张图片
主动触发计算

​ public boolean complete(T value) 是否打断get方法立即返回括号值
JUC—CompletableFuture笔记_第20张图片JUC—CompletableFuture笔记_第21张图片

2) 对计算结果进行处理

1. thenApply 计算结果存在依赖关系,这两个线程串行化
JUC—CompletableFuture笔记_第22张图片

由于存在依赖关系(当前步错,不走下一步),当前步骤有异常的话就叫停。
JUC—CompletableFuture笔记_第23张图片JUC—CompletableFuture笔记_第24张图片
2. handle 有异常也可以往下一步走,根据带的异常参数可以进一步处理
JUC—CompletableFuture笔记_第25张图片
结果
JUC—CompletableFuture笔记_第26张图片
总结
JUC—CompletableFuture笔记_第27张图片
一般用不带尾巴的
JUC—CompletableFuture笔记_第28张图片

3) 对计算结果进行消费

接收任务的处理结果,并消费处理,无返回结果

thenAccept 

JUC—CompletableFuture笔记_第29张图片
任务之间的顺序执行
JUC—CompletableFuture笔记_第30张图片

  • thenRun 无输入,无返回
  • thenAccept 有输入,无返回
  • thenApply 有输入,有返回
4) 对计算速度进行选用

谁快用谁 applyToEither
JUC—CompletableFuture笔记_第31张图片

5) 对计算结果进行合并

两个CompletionStage任务都完成后,最终能把两个任务的结果一起交给thenCombine 来处理

先完成的先等着,等待其它分支任务

thenCombine
JUC—CompletableFuture笔记_第32张图片

你可能感兴趣的:(JUC,java,开发语言,后端)