JAVA异步任务-CompletableFuture

1.概述

在jdk1.8中,引入了CompletableFuture,它扩展了Future和CompletionStage,可以在任务完成后触发回调,实现异步调用。在此之前若要设置回调一般会使用guava的ListenableFuture,但引入回调之后会陷入无穷的回调地狱中,导致编码难以阅读和理解。CompletableFuture对Future进行了扩展,可以通过设置回调的方式处理计算结果,同时也支持组合,支持任务编排,在一定程度上解决了回调地狱和代码难以阅读问题。本文将分析CompletableFuture的使用及实现原理。

2.案例分析

2.1 CompletableFuture使用

2.1.1 创建CompletableFuture

1.利用 runAsync(Runnable runnable)创建
runAsync方法入参是Runnable、executor,如果入参有executor,则使用executor来执行异步任务。需要注意的是,runAsync方法只执行方法里面内容,不携带返回结果。

public static CompletableFuture<Void>  runAsync(Runnable runnable)
public static CompletableFuture<Void>  runAsync(Runnable runnable, Executor executor)

//使用runAsync(Runnable runnable)创建CompletableFuture对象如下
   CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> {
   
            try {
   
                //Thread.sleep(1000);
                System.out.println("runAsync  " + Thread.currentThread().getName());
            } catch (Exception e) {
   
                e.printStackTrace();
            }
        });

//使用runAsync(Runnable runnable, Executor executor)创建CompletableFuture对象
       final ExecutorService executorService = Executors.newFixedThreadPool(2);
        CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> {
   
            try {
   
                //Thread.sleep(1000);

            } catch (Exception e) {
   
                e.printStackTrace();
            }
            System.out.println("runAsync  " + Thread.currentThread().getName());
        }, executorService);

2.利用supplyAsync(Supplier supplier)创建

supplyAsync(Supplier supplier)异步执行并返回结果的任务,适合需要返回值的场景。


public static <U> CompletableFuture<U>  supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U>  supplyAsync(Supplier<U> supplier, Executor executor)

//使用supplyAsync(Runnable runnable)创建CompletableFuture对象如下
      CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
   
            try {
   
                //Thread.sleep(5000);
            } catch (Exception e) {
   
                e.printStackTrace();
            }
            System.out.println("supplyAsync  " + Thread.currentThread().getName());
            return "hello";
        });



//使用supplyAsync(Runnable runnable,Executor executor)创建CompletableFuture对象如下
 CompletableFuture<String> cf = CompletableFuture.supplyAsync(() -> {
   
            try {
   
                //Thread.sleep(5000);
            } catch (Exception e) {
   
                e.printStackTrace();
            }
            System.out.println("supplyAsync  " + Thread.currentThread().getName());
            return "hello";
        }, executorService);


2.1.2 完成complete和取消cancel操作

complete(V value):手动完成CompletableFuture,强制设置返回结果;
cancel(boolean mayInterruptIfRunning):取消任务,入参为true表明中断正在执行的任务;

//强制设置返回结果,即使任务有返回结果,也会被complete强制返回结果替代
 public static String complete() throws ExecutionException, InterruptedException {
   
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> 
Java中,`CompletableFuture`是一个用于处理异步计算的强大工具,它提供了一种线程安全的方式来示一个最终结果可能会依赖于零个、一个或多个其他计算的结果。如果你想等待所有的异步任务完成后继续执行,可以使用以下几个关键方法: 1. `thenApply()` 或 `thenAccept()`:当你有一个函数想要接收到上一个任务的结果并立即返回一个新的Future,你可以使用这两个方法。它们都接收一个Function或Consumer作为参数,当上一个任务完成时,会应用这个函数或消费结果。 2. `thenCombine()`:如果你有多个独立的任务,每个任务都有自己的Future,并且你想将它们的结果合并到一起,可以使用`thenCombine()`,它接受另一个CompletableFuture,然后对每个 Future 应用提供的 Function,最后返回一个新的 Future。 3. `thenAllOf()` 或 `allOf()`:这两个方法用于等待列中的所有CompletableFuture完成。`thenAllOf()`是链式操作,而`allOf()`则是静态工厂方法,返回一个新的Future,该Future只有在所有输入Futures都完成时才会完成。 4. `.join()` 或 `.get()`:如果你真的想阻塞当前线程直到所有异步任务完成,可以调用`.join()`方法,这会阻塞直到Future完成。但请注意,`.get()`方法会抛出异常如果超时,所以通常不是首选,除非你知道需要这种阻塞行为。 示例: ```java List<CompletableFuture<String>> futures = ... // 初始化异步任务 CompletableFuture<Void> allDone = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); allDone.thenAccept(result -> { System.out.println("所有任务已完成"); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值