CompletableFuture的用法及简要原理

//自定义线程池
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(8,16,20, TimeUnit.SECONDS,new LinkedBlockingDeque<>(20), Executors.defaultThreadFactory(), (r, executor1) -> new Thread(r).start());
 System.out.println("Main 线程名称: "+Thread.currentThread().getName());

//runAsync 开启一个异步任务,接受一个Runnable,可选传入自定义线程池
CompletableFuture.runAsync(()-> System.out.println(Thread.currentThread().getName()+"     CSDN——Mutou_ren  CompletableFuture.runAsync"),executor);
//supplyAsync 开启一个异步任务,接受一个supplier函数,如果不指定自定义线程池默认都是使用ForkJoinPool.commonPool线程池
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(()-> (Thread.currentThread().getName()+"     CSDN——Mutou_ren  CompletableFuture.supplyAsync"));
System.out.println(Thread.currentThread().getName()+"   "+future1.get());

在这里插入图片描述

thenRun

//thenRun接受一个runnable ,无法读取前面的结果
 CompletableFuture.supplyAsync(()->{
            System.out.println("thenRun前置准备睡眠");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thenRun前置睡眠结束");
            return 1;
        }).thenRun(()-> System.out.println("then run 执行,无法拿到前置任务的结果"));

在这里插入图片描述

thenAccept

//thenAccept可以接收一个consumer,能读取到前面的结果
 CompletableFuture.supplyAsync(()->{
            System.out.println("thenAccept前置准备睡眠");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thenAccept前置睡眠结束");
            return "thenAccept前置返回值";
        }).thenAccept(e-> System.out.println("then accept 可以收到前置任务的结果为:"+e));

在这里插入图片描述

thenApply

//thenApply接收一个function,可以读取前面的结果并返回新的结果,
 CompletableFuture future2 = CompletableFuture.supplyAsync(()->{
            System.out.println("thenApply前置准备睡眠");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thenAccept前置睡眠结束");
            return "thenApply前置返回值";
        }).thenApply(e->e+" then apply 添加");
       System.out.println(Thread.currentThread().getName()+future2.get());

在这里插入图片描述

whenComplete

  CompletableFuture future3 = CompletableFuture.supplyAsync(()->{
            System.out.println("thenAccept前置准备睡眠");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thenAccept前置睡眠结束");
            return "future3";
        });
//设置回调,t代表异常thrown
future3.whenComplete((e,t)-> System.out.println(Thread.currentThread().getName()+"whenComplete "+e));

在这里插入图片描述

thenCombine

//收集前面的和当前的CompletableFuture 的返回值作为参数,传递给function
 CompletableFuture future7 = CompletableFuture.supplyAsync(()->"then").thenCombine( CompletableFuture.supplyAsync(()->"combine"),(a,b)-> a+" "+b);
        System.out.println(future7.get());

在这里插入图片描述

thenCompose

//前面的CompletableFuture 返回值可以作为下一个CompletableFuture 的参数
CompletableFuture future8 = CompletableFuture.supplyAsync(()->"then").thenCompose(str -> CompletableFuture.supplyAsync(()-> str+" compose"));
        System.out.println(future8.get());

在这里插入图片描述

allof

//模拟耗时操作
public static Integer getResult(int integer){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return integer;
    }
    
  List<CompletableFuture<Integer>> futureList = new ArrayList(50);
        for (int i=0;i<50;i++){
            futureList.add(CompletableFuture.supplyAsync(()->getResult(1),executor));
        }
//在另一个流上对每个future进行join操作,等价allof
List<Integer> resultList = futureList.stream().map(e -> e.join()).collect(Collectors.toList());
System.out.println(resultList.size());

在这里插入图片描述

//将多个future合并成一个等待
CompletableFuture all = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()]));
//这里返回就代表列表中所有的future全返回了
all.get();
System.out.println(futureList.stream().filter(e -> !e.isDone()).count());

在这里插入图片描述

anyof

 List<CompletableFuture<Integer>> futureList = new ArrayList(50);
        for (int i=0;i<50;i++){
            futureList.add(CompletableFuture.supplyAsync(()->getResult(1),executor));
        }
CompletableFuture any = CompletableFuture.anyOf(futureList.toArray(new CompletableFuture[futureList.size()]));
//这里返回就代表列表中有future返回了
any.get();
System.out.println(futureList.stream().filter(e -> !e.isDone()).count());

在这里插入图片描述

原理

CompletableFuture.supplyAsync等方法中,实际上就是新建了一个CompletableFuture对象,然后使用线程池运行任务并立即将这个CompletableFuture对象返回。在线程池运行任务时,会在run后将结果通过future.complete()或异常future.completeExceptionlly()设置到CompletableFuture对象中

Future.get

调用get时会判断任务状态是否结束,若没有结束则构建成等待节点并park;当任务完成进行set结果或异常set异常时,会通过finishCompletion()将所有等待的节点线程unpark并删除节点,思想还是AQS那套思想

发布了98 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Mutou_ren/article/details/103947334