JUC—CompletableFuture笔记

1. Future和Callable接口

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

Callable接口中定义了需要有返回的任务需要实现的方法。

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

2. FutureTask

本源的Future接口相关架构

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 介绍

类架构说明

接口CompletionStage

代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段,有些类似Linux系统的管道分隔符传参数。

类CompletableFuture 可以完全替代FutureTask

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


代码演示:

结果:

2) supplyAsync() 有 返回值

​ CompletableFuture supplyAsync(Supplier supplier)

代码演示:

结果:


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

上述方法的Executor executor参数说明

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


CompletableFuture四个函数

使用:

结果:


CompletableFuture的优点

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

函数式编程已经主流

​ Lambda +Stream+链式调用+Java8函数式编程带走

3.4 说说join和get对比

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

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

如果有异常在此抛出

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值

主动触发计算

​ public boolean complete(T value) 是否打断get方法立即返回括号值
 打断失败 打断成功

2) 对计算结果进行处理

1. thenApply 计算结果存在依赖关系,这两个线程串行化

由于存在依赖关系(当前步错,不走下一步),当前步骤有异常的话就叫停。

2. handle 有异常也可以往下一步走,根据带的异常参数可以进一步处理

结果

总结

一般用不带尾巴的

3) 对计算结果进行消费

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

thenAccept 


任务之间的顺序执行

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

谁快用谁 applyToEither

5) 对计算结果进行合并

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

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

thenCombine

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值