风离不摆烂学习日志Day18 Java 异步线程池 CompletableFuture

关于CompletableFuture

image-20230110135608563

可以看到 supplyAsync 适合处理有返回值的异步任务 runAsync适合处理无需返回的异步任务

这里重点看一下有返回值的异步任务(大多数场景下)

异步异常处理

   if(!futureOne.exceptionally(e -> {
            System.out.println("futureOne " + Thread.currentThread().getId() + "---" + Thread.currentThread().getName() + "---" + "第一个异步任务执行失败  程序将退出");
            return null;
        }).isCompletedExceptionally()){
            return;
        }

上面这行代码的意思是 如果异步任务出现异常 首先对异常进行处理 然后退出程序 (注意这个方法是阻塞的 如果只想得到最后的结果 可以把这行语句放到所有异步任务之后)这样就不会阻塞程序的正常异步运行了

image-20230110142242755

链式异步任务(接收上一个任务的返回值作为入参)

//继续异步或者 同步任务 这个得到的返回值还是completableFuture 所以可以继续链式进行任务
CompletableFuture completableFuture = futureOne.thenApply(result -> {
    System.out.println(result);
    return result;
});
futureOne.thenApplyAsync(result ->{
    System.out.println(result);

    return result;
});

AnyOf 与 AllOf(常用)

anyOf() 的参数是多个给定的 CompletableFuture,当其中的任何一个完成时,方法返回这个 CompletableFuture

allOf()方法用来实现多 CompletableFuture 的同时返回。

常用方法总结图例

img

案例实践 泡茶

package top.flya.utils;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

public class CompletableFutureTest {

    public static void main(String[] args) {

        //任务1:洗水壶->烧开水
        CompletableFuture<Void> f1 = CompletableFuture
                .runAsync(() -> {
                    System.out.println("T1:洗水壶...");
                    sleep(1, TimeUnit.SECONDS);

                    System.out.println("T1:烧开水...");
                    sleep(9, TimeUnit.SECONDS);
                });
        //任务2:洗茶壶->洗茶杯->拿茶叶
        CompletableFuture<String> f2 = CompletableFuture
                .supplyAsync(() -> {
                    System.out.println("T2:洗茶壶...");
                    sleep(1, TimeUnit.SECONDS);

                    System.out.println("T2:洗茶杯...");
                    sleep(2, TimeUnit.SECONDS);

                    System.out.println("T2:拿茶叶...");
                    sleep(1, TimeUnit.SECONDS);


                    int error = 1/0;
                    return "龙井";
                });
        //检测任务1和任务2是否出异常
       if(f2.exceptionally(t -> {
           System.out.println("执行失败:" + t.getMessage());
           return "异常xxxx";
       }).isCompletedExceptionally()){
            System.out.println("任务2出现异常");
            return;
        }
        //任务3:任务1和任务2完成后执行:泡茶
        CompletableFuture<String> f3 = f1.thenCombine(f2, (__,tf) -> {
            System.out.println("T1:拿到茶叶:" + tf);
            System.out.println("T1:泡茶...");
            return "上茶:" + tf;
        });
        //等待任务3执行结果
        System.out.println(f3.join());
    }

    static void sleep(int t, TimeUnit u){
        try {
            u.sleep(t);
        } catch (InterruptedException e) {
        }
    }
}