【发布时间】:2020-11-21 06:23:08
【问题描述】:
在生产环境中发现关于CompletableFuture.supplyAsync()的问题
我们有一个批处理方法,如下所示:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
public class CompletableFutureProblem {
public void batchOperation(){
List<String> stringList = new ArrayList<>();
stringList.add("task1");
stringList.add("task2");
List<CompletableFuture<String>> futures = new ArrayList<>();
stringList.parallelStream().forEach(str -> {
CompletableFuture<String> response = restApiCall(str);
futures.add(response);
});
//futures.add(null);
CompletableFuture<Void> result = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
CompletableFuture<List<String>> convertedResult = result.thenApply(v ->
futures.stream().map(CompletableFuture::join).collect(Collectors.toList())
);
try {
List<String> finishedTask = convertedResult.get();
System.out.println(finishedTask.toString());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
public CompletableFuture<String> restApiCall(String str){
return CompletableFuture.supplyAsync(() -> {
return "Complete-" + str;
});
}
public static void main(String[] args) {
CompletableFutureProblem problem = new CompletableFutureProblem();
problem.batchOperation();
}
}
当一切正常时将打印: [完成任务2,完成任务1]
但是,有时它会在生产中引发如下异常:
Exception in thread "main" java.lang.NullPointerException
at java.util.concurrent.CompletableFuture.andTree(CompletableFuture.java:1320)
at java.util.concurrent.CompletableFuture.allOf(CompletableFuture.java:2238)
at third.concurrent.CompletableFutureProblem.batchOperation(CompletableFutureProblem.java:20)
at third.concurrent.CompletableFutureProblem.main(CompletableFutureProblem.java:40)
我查了CompletableFuture.allOf()源码发现如果列表futures包含null,例如futures.add(null),就会抛出异常,但我真的不知道restApiCall方法中的CompletableFuture.supplyAsync()在什么情况下会返回null?
感谢您的耐心阅读这篇长文。
【问题讨论】:
标签: java multithreading java-8 concurrency nullpointerexception