CompletableFuture 有返回值的用法

CompletableFuture 是 Java 8 引入的用于异步编程的类,特别适合处理有返回值的异步任务。下面从基本用法到组合操作,详细介绍其常见场景:

1. 基本异步任务(带返回值)

使用 supplyAsync() 方法执行有返回值的异步任务:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建异步任务(使用 ForkJoinPool 线程池)
        CompletableFuture future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000); // 模拟耗时操作
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "Hello from CompletableFuture!"; // 返回值
        });

        // 获取任务结果(阻塞当前线程)
        String result = future.get();
        System.out.println(result); // 输出: Hello from CompletableFuture!
    }
}

  • 关键点
  • supplyAsync(Supplier supplier):接收一个带返回值的 Supplier。
  • future.get():阻塞等待结果,可能抛出 ExecutionException(任务异常)或 InterruptedException(线程中断)。

2. 自定义线程池

使用 ExecutorService 自定义线程池,避免使用默认的 ForkJoinPool:

import java.util.concurrent.*;

public class CustomThreadPoolExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建固定大小的线程池
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // 指定线程池执行异步任务
        CompletableFuture future = CompletableFuture.supplyAsync(() -> {
            return "Task executed in custom thread pool";
        }, executor);

        System.out.println(future.get()); // 获取结果
        executor.shutdown(); // 关闭线程池
    }
}

3. 处理任务完成后的结果

使用 thenApply() 或 thenAccept() 处理结果:

CompletableFuture future = CompletableFuture.supplyAsync(() -> "Hello")
    .thenApply(result -> result + " World") // 转换结果
    .thenApply(String::toUpperCase); // 继续处理结果

System.out.println(future.get()); // 输出: HELLO WORLD

  • 区别
  • thenApply(Function):有返回值,可链式调用。
  • thenAccept(Consumer):无返回值,用于消费结果。

4. 异常处理

使用 exceptionally() 或 handle() 处理异常:

CompletableFuture future = CompletableFuture.supplyAsync(() -> {
    if (Math.random() < 0.5) {
        throw new RuntimeException("Oops!");
    }
    return "Success";
}).exceptionally(ex -> {
    System.out.println("Error: " + ex.getMessage());
    return "Default Value"; // 异常时的默认返回值
});

System.out.println(future.get()); // 可能输出: Default Value

5. 组合多个 CompletableFuture

5.1 串行执行(依赖关系)

CompletableFuture future = CompletableFuture.supplyAsync(() -> "Hello")
    .thenCompose(result -> // 类似 flatMap
        CompletableFuture.supplyAsync(() -> result + " World"));

System.out.println(future.get()); // 输出: Hello World

5.2 并行执行(合并结果)

CompletableFuture future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture future2 = CompletableFuture.supplyAsync(() -> " World");

CompletableFuture combined = future1.thenCombine(future2, (s1, s2) -> s1 + s2);
System.out.println(combined.get()); // 输出: Hello World

5.3 任意一个完成即返回

CompletableFuture future1 = CompletableFuture.supplyAsync(() -> {
    try { Thread.sleep(2000); } catch (InterruptedException e) {}
    return "Result from Future 1";
});

CompletableFuture future2 = CompletableFuture.supplyAsync(() -> {
    try { Thread.sleep(1000); } catch (InterruptedException e) {}
    return "Result from Future 2";
});

CompletableFuture any = CompletableFuture.anyOf(future1, future2);
System.out.println(any.get()); // 输出: Result from Future 2(更快完成)
 
    

6. 批量执行多个任务

使用 allOf() 等待所有任务完成:

CompletableFuture future1 = CompletableFuture.supplyAsync(() -> "A");
CompletableFuture future2 = CompletableFuture.supplyAsync(() -> "B");
CompletableFuture future3 = CompletableFuture.supplyAsync(() -> "C");

CompletableFuture allFutures = CompletableFuture.allOf(future1, future2, future3);

// 获取所有结果
CompletableFuture> allResults = allFutures.thenApply(v -> 
    Stream.of(future1, future2, future3)
          .map(CompletableFuture::join)
          .collect(Collectors.toList())
);

System.out.println(allResults.get()); // 输出: [A, B, C]

总结

  • 核心方法
  • supplyAsync():创建有返回值的异步任务。
  • thenApply()/thenAccept():处理结果。
  • exceptionally()/handle():异常处理。
  • thenCompose():任务串行。
  • thenCombine():合并并行任务结果。
  • allOf()/anyOf():批量处理多个任务。

通过 CompletableFuture,可以优雅地处理复杂的异步逻辑,避免回调地狱,让代码更易读和维护。

你可能感兴趣的:(Java并发编程,java,开发语言)