Java并发编程框架性能测试:ForkJoinPool vs ExecutorService对比
在Java并发编程中,ForkJoinPool和ExecutorService是两个常用的线程池实现。本文通过实际测试数据对比两者在不同场景下的性能表现。
测试环境
- JDK 11
- Intel i7-8750H CPU @ 2.20GHz
- 16GB RAM
测试代码
public class ConcurrentTest {
public static void main(String[] args) {
int tasks = 1000;
int parallelism = Runtime.getRuntime().availableProcessors();
// ExecutorService测试
long start = System.nanoTime();
ExecutorService executor = Executors.newFixedThreadPool(parallelism);
for (int i = 0; i < tasks; i++) {
executor.submit(() -> {
// 模拟计算任务
Math.pow(Math.random(), 2);
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
long executorTime = System.nanoTime() - start;
// ForkJoinPool测试
start = System.nanoTime();
ForkJoinPool forkJoinPool = new ForkJoinPool(parallelism);
for (int i = 0; i < tasks; i++) {
forkJoinPool.submit(() -> {
Math.pow(Math.random(), 2);
});
}
forkJoinPool.shutdown();
forkJoinPool.awaitTermination(1, TimeUnit.MINUTES);
long forkJoinTime = System.nanoTime() - start;
System.out.println("ExecutorService耗时: " + executorTime/1000000 + "ms");
System.out.println("ForkJoinPool耗时: " + forkJoinTime/1000000 + "ms");
}
}
测试结果
| 任务数量 | ExecutorService | ForkJoinPool |
|---|---|---|
| 100 | 24ms | 28ms |
| 500 | 112ms | 98ms |
| 1000 | 236ms | 204ms |
结论
在本测试中,ForkJoinPool在处理大量小任务时表现略优。这主要因为ForkJoinPool采用了工作窃取算法,在任务分布不均时能够更好地利用CPU资源。ExecutorService则更适合处理大小相对均匀的任务。
建议:对于计算密集型任务且任务粒度较小的场景,优先考虑使用ForkJoinPool;而对于I/O密集型或任务负载不均衡的场景,ExecutorService更为合适。

讨论