面试题答案
一键面试优化思路
- 任务拆分与并行执行:将大量任务拆分成多个小批次并行执行,减少单个
allOf
方法处理的任务数量。例如,把1000个任务分成10组,每组100个任务,每组并行执行,然后再对每组的结果进行汇总。 - 线程池优化:使用合理配置的线程池,根据系统资源(如CPU核心数、内存等)来设置线程池的大小,避免线程过多导致的上下文切换开销。比如,根据CPU核心数设置线程池大小为
Runtime.getRuntime().availableProcessors() * 2
。 - 减少阻塞操作:在任务执行过程中,尽量减少I/O等阻塞操作,若无法避免,可以采用异步I/O方式(如NIO)。
- 流处理:利用Java 8的流来处理任务,流的并行处理特性可以提高执行效率。
关键代码片段
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class CompletableFuturePerformanceOptimization {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 线程池配置
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
// 假设这是要执行的任务列表
List<CompletableFuture<String>> allTasks = new ArrayList<>();
IntStream.range(0, 1000).forEach(i -> {
CompletableFuture<String> task = CompletableFuture.supplyAsync(() -> {
// 模拟任务执行
return "Task " + i + " completed";
}, executor);
allTasks.add(task);
});
// 任务拆分与并行执行
int batchSize = 100;
List<CompletableFuture<Void>> batchFutures = new ArrayList<>();
for (int i = 0; i < allTasks.size(); i += batchSize) {
List<CompletableFuture<String>> subList = allTasks.subList(i, Math.min(i + batchSize, allTasks.size()));
CompletableFuture<Void> batchFuture = CompletableFuture.allOf(subList.toArray(new CompletableFuture[0]));
batchFutures.add(batchFuture);
}
// 等待所有批次任务完成
CompletableFuture<Void> allBatchFuture = CompletableFuture.allOf(batchFutures.toArray(new CompletableFuture[0]));
allBatchFuture.get();
// 获取所有任务结果
List<String> results = allTasks.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
results.forEach(System.out::println);
executor.shutdown();
}
}
上述代码首先将1000个任务按每100个一批进行拆分,然后并行执行每个批次的任务。通过合理配置线程池,减少了单个allOf
处理的任务数量,提高了执行效率。最后获取并打印所有任务的结果。