CompletableFuture.allOf两种数组传参区别及顺序任务返回List问询
CompletableFuture相关问题解答
一、CompletableFuture.allOf两种数组传入方式的区别
这两种写法在功能上完全等价,最终都会把futuresList里的所有CompletableFuture元素传给allOf方法,唯一差异在于数组创建的细节:
- 传入
new CompletableFuture[0]时,List.toArray(T[])会发现传入的数组长度不足以容纳所有元素,因此会重新创建一个和列表大小匹配的数组来填充元素。 - 传入
new CompletableFuture[futuresList.size()]时,List.toArray(T[])会直接使用这个长度刚好匹配的数组来填充元素,不会额外创建新数组。
日常开发中两种写法都可用,后者更直观,前者的额外数组创建开销在现代JVM下几乎可以忽略。
二、串行执行任务并返回CompletableFuture<List>
要确保第一个任务完成后再执行第二个,最终返回包含结果的CompletableFuture<List>,可以通过thenCompose串联任务,再用thenApply打包结果:
// 定义第一个异步任务 CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "任务1执行结果"); // 定义依赖第一个任务结果的第二个异步任务 CompletableFuture<String> task2(String task1Result) { return CompletableFuture.supplyAsync(() -> task1Result + " -> 任务2执行结果"); } // 串行执行并返回结果列表的Future CompletableFuture<List<String>> serialResult = task1.thenCompose(result1 -> task2(result1).thenApply(result2 -> Arrays.asList(result1, result2)) );
如果第二个任务不需要依赖第一个任务的结果,仅需保证执行顺序,可简化为:
CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> { /* 任务1逻辑 */ }); CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> "任务2结果"); CompletableFuture<List<String>> serialResult = task1.thenCompose(v -> task2.thenApply(result2 -> Arrays.asList("任务1已完成", result2)) );
三、先创建结果列表,通过CompletableFuture<List>返回
分两种场景处理:
场景1:直接返回已就绪的列表
如果结果列表已经提前准备好,用completedFuture直接包装即可:
List<String> preCreatedList = Arrays.asList("预定义结果1", "预定义结果2"); CompletableFuture<List<String>> futureList = CompletableFuture.completedFuture(preCreatedList);
场景2:异步填充列表后返回
如果需要先执行异步逻辑填充已创建的列表,再返回该列表的Future:
// 提前创建列表(注意多线程场景需用线程安全集合,比如CopyOnWriteArrayList) List<String> resultList = new CopyOnWriteArrayList<>(); CompletableFuture<List<String>> futureList = CompletableFuture.runAsync(() -> { // 异步执行填充逻辑 resultList.add("异步添加结果1"); resultList.add("异步添加结果2"); }).thenApply(v -> resultList);
内容的提问来源于stack exchange,提问作者Ked 123
相关产品推荐
相关产品推荐

