Java中的CompletableFuture是java.util.concurrent包下的重要类,它实现了CompletionStage和Future接口,提供了丰富的异步编程能力,支持任务链式调用、组合、异常处理等功能,相比传统的Future接口更加灵活易用。

CompletableFuture基础使用
CompletableFuture最常用的场景是发起异步任务,默认会使用ForkJoinPool.commonPool()作为线程池执行任务,也可以通过指定自定义线程池来控制任务执行线程。
发起无返回值的异步任务
使用runAsync方法可以发起一个没有返回结果的异步任务,适合执行不需要返回数据的后台操作。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class CompletableFutureDemo {
public static void main(String[] args) {
// 无返回值异步任务
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("异步任务执行完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 等待任务完成
future.join();
System.out.println("主线程继续执行");
}
}
发起有返回值的异步任务
使用supplyAsync方法可以发起有返回结果的异步任务,任务执行完成后会返回对应的结果数据。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureDemo2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 有返回值异步任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "异步任务返回结果";
});
// 获取结果
String result = future.get();
System.out.println("获取到的结果:" + result);
}
}
CompletableFuture链式调用
CompletableFuture支持链式调用,可以在任务完成后接着执行后续操作,不需要手动阻塞等待结果。
thenApply转换结果
thenApply方法可以在获取到上一个任务的结果后,对结果进行转换处理,返回新的结果。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo3 {
public static void main(String[] args) {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
return 10;
}).thenApply(result -> {
// 对结果做乘2处理
return result * 2;
});
System.out.println("最终结果:" + future.join());
}
}
thenAccept消费结果
thenAccept方法用于消费上一个任务的结果,不需要返回新的结果,适合执行后续的业务处理逻辑。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo4 {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
return "处理完成的数据";
}).thenAccept(result -> {
System.out.println("消费结果:" + result);
}).join();
}
}
多任务组合处理
实际开发中经常需要处理多个异步任务的组合场景,CompletableFuture提供了对应的API支持任务并行和串行组合。
等待所有任务完成
使用CompletableFuture.allOf可以等待多个异步任务全部完成后再执行后续操作。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class CompletableFutureDemo5 {
public static void main(String[] args) {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "任务1结果";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "任务2结果";
});
// 等待两个任务都完成
CompletableFuture<Void> allFuture = CompletableFuture.allOf(future1, future2);
allFuture.join();
System.out.println("所有任务都执行完成");
System.out.println("任务1结果:" + future1.join());
System.out.println("任务2结果:" + future2.join());
}
}
等待任意一个任务完成
使用CompletableFuture.anyOf可以等待多个异步任务中任意一个完成就执行后续操作。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class CompletableFutureDemo6 {
public static void main(String[] args) {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "任务1结果";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "任务2结果";
});
// 等待任意一个任务完成
CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2);
System.out.println("最先完成的任务结果:" + anyFuture.join());
}
}
异常处理
异步任务执行过程中可能出现异常,CompletableFuture提供了多种方式处理异常情况。
exceptionally处理异常
exceptionally方法可以在任务出现异常时返回兜底结果,避免异常向上抛出。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo7 {
public static void main(String[] args) {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
// 模拟异常情况
int a = 1 / 0;
return a;
}).exceptionally(ex -> {
System.out.println("捕获到异常:" + ex.getMessage());
// 返回兜底结果
return 0;
});
System.out.println("最终结果:" + future.join());
}
}
handle处理结果与异常
handle方法可以同时处理正常结果和异常情况,无论任务是否成功都会执行。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo8 {
public static void main(String[] args) {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
return 10;
}).handle((result, ex) -> {
if (ex != null) {
System.out.println("出现异常:" + ex.getMessage());
return 0;
}
return result * 3;
});
System.out.println("处理结果:" + future.join());
}
}
自定义线程池使用
默认情况下CompletableFuture使用公共的ForkJoin线程池,如果异步任务较多或者任务执行时间较长,建议使用自定义线程池避免影响其他任务执行。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CompletableFutureDemo9 {
public static void main(String[] args) {
// 创建自定义线程池
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "使用自定义线程池执行任务";
}, executor);
System.out.println(future.join());
// 关闭线程池
executor.shutdown();
}
}
使用注意事项
- 默认线程池适合执行短时间的小任务,长时间任务或者大量任务建议使用自定义线程池,避免阻塞公共线程池
- 调用
get方法会阻塞当前线程直到任务完成,尽量使用join方法或者回调方式处理结果,避免不必要的阻塞 - 链式调用中的方法默认会在上一个任务的执行线程中运行,如果需要指定线程执行可以传入自定义线程池参数
- 异常处理要覆盖所有可能的异常场景,避免未捕获的异常导致程序出现问题
CompletableFutureJava异步编程Future异步任务线程池修改时间:2026-06-23 13:21:39