CompletableFuture

CompletableFuture是Java8引入的,在Future的基础上实现了异步编排功能,并且可以使用complete方法在不同线程中通信。

Future

Future类用来表示一个异步计算的结果,可以用来获取计算的结果或者取消任务的执行。

主要方法有:

isDone():判断任务是否已经完成。
get():获取异步任务的执行结果,如果任务还没有完成则会阻塞当前线程直到任务完成。
cancel():取消异步任务的执行。
isCancelled():判断任务是否已经被取消。

运用场景:当需要处理耗时任务,我们可以将耗时任务交给子线程去异步执行,当耗时任务处理完后我们可以在主线程通过Future获取处理结果。我们可以利用future+线程池改善计算性能。

举个例子:我们需要统计多个网站内容长度,假如串行计算的话,我们的耗时就是单独计算每个网站长度所需要时间的和,但如果我们并行计算计算的话可以节省大量时间。

import java.util.concurrent.*;

//通过Future对象可以获取每个任务的执行结果(网站内容长度),最后我们将各个网站内容的长度相加,得到总的内容长度并输出。这样就实现了并行地获取多个网站内容的长度的统计。
public class FutureApplicationExample {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        Future<Integer> future1 = executor.submit(() -> getContentLength("https://www.google.com"));
        Future<Integer> future2 = executor.submit(() -> getContentLength("https://www.facebook.com"));
        Future<Integer> future3 = executor.submit(() -> getContentLength("https://www.twitter.com"));

        int totalLength = future1.get() + future2.get() + future3.get();
        System.out.println("Total length of content: " + totalLength);

        executor.shutdown();
    }

    private static int getContentLength(String url) {
        // 发起HTTP请求获取网站内容,并返回内容长度  
        // 这里用休眠时间模拟HTTP请求  
        try {
            Thread.sleep(2000); // 模拟HTTP请求  
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return url.length(); // 返回内容长度  
    }
}

缺点:Future只能同步(通过get方法阻塞等待结果或者isDone方法轮询查询任务是否结束)等待任务结束(或成功、或失败)才能得到结果。

CompletableFuture

Java8引入了CompletableFuture,CompletableFutrue实现了Future接口和ComletionStage接口,CompletionStage接口定义了任务编排的方法,执行某一阶段,可以向下执行后续阶段,除了拥有Future的功能以外还能实现异步编程。另外,还可以使用complete方法在不同线程中通信。

常用方法:

1. supplyAsync(): 创建一个CompletableFuture对象并异步执行一个任务,并返回任务的结果。

CompletableFuture<Integer> future 
= CompletableFuture.supplyAsync(() -> 42); int result = future.get(); // result = 42

2. thenApply(): 当CompletableFuture的任务完成后,对任务的结果进行转换处理,并返回新的结果。 

CompletableFuture<String> future 
= CompletableFuture.supplyAsync(() -> "Hello") .thenApply(s -> s + " World"); 
String result = future.get(); // result = "Hello World"

3. thenCombine(): 当两个CompletableFuture都完成后,将它们的结果进行组合处理,并返回新的结果。 

CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10); 
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20); 
CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (x, y) -> x + y);
int result = combinedFuture.get(); // result = 30

4. thenAccept(): 当CompletableFuture的任务完成后,对任务的结果进行消费处理,没有返回值。 

CompletableFuture<Void> future = 
CompletableFuture.supplyAsync(() -> "Hello") 
.thenAccept(System.out::println); future.get(); // 输出 "Hello"

5. exceptionally(): 当CompletableFuture的任务执行过程中出现异常时,可以进行异常处理并返回默认值。 

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 10 / 0) 
.exceptionally(e -> { System.out.println("Error occurred: " + e); 
return 0; // 返回默认值 
}); 
int result = future.get(); // result = 0

6. thenCompose(): 将连续的CompletableFuture任务连接在一起,将一个任务的结果作为输入传递给另一个任务。

CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 5); 
CompletableFuture<Integer> future2 = future1.thenCompose(result -> 
CompletableFuture.supplyAsync(() -> result * 2)); 
int result = future2.get(); // result = 10

7. allOf(): 该方法接受一个CompletableFuture数组作为参数,并创建一个新的CompletableFuture对象,该对象在所有输入的CompletableFuture都完成后才会完成。

CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);  
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);  
CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> 30);  

CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);  
// 等待所有CompletableFuture完成  

8. anyOf(): 该方法接受一个CompletableFuture数组作为参数,并创建一个新的CompletableFuture对象,该对象在任何一个输入的CompletableFuture完成后就会完成。

anyOf(): 该方法接受一个CompletableFuture数组作为参数,并创建一个新的CompletableFuture对象,该对象在任何一个输入的CompletableFuture完成后就会完成。
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);  
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);  

CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future1, future2);  

Object result = anyOfFuture.get(); // 获取第一个完成的CompletableFuture的结果  

9. complete(): CompletableFuture类中的complete()方法用于手动触发CompletableFuture的计算结果。通过complete()方法,可以手动设置CompletableFuture的计算结果,而不是等待任务自动完成。这在一些特定场景下比较有用,比如与外部事件或条件相关的异步任务处理。

CompletableFuture<Integer> future = new CompletableFuture<>();  

// 模拟异步任务,1秒后手动设置计算结果为42  
new Thread(() -> {  
    try {  
        Thread.sleep(1000);  
        future.complete(42);  
    } catch (InterruptedException e) {  
        future.completeExceptionally(e);  
    }  
}).start();  

// 获取CompletableFuture的计算结果  
try {  
    int result = future.get(); // 阻塞直到任务完成并获取结果  
    System.out.println("计算结果为: " + result);  
} catch (Exception e) {  
    System.out.println("计算出错: " + e.getMessage());  
}

获取异步计算的结果也非常简单,直接调用 get() 方法即可。调用 get() 方法的线程会阻塞直到 CompletableFuture 完成运算。

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值