要计算这些任务的执行时间,可以分析线程池的处理过程:
-
核心线程池:首先,10个核心线程会立即处理10个任务。
-
阻塞队列:接下来,阻塞队列会接收30个任务。
-
最大线程池:由于阻塞队列已满,剩下的5个任务会激活最大线程池中的10个非核心线程中的5个。
执行过程:
-
第一批任务:
- 10个核心线程处理10个任务。
- 5个最大线程处理5个任务。
- 共15个任务同时进行,耗时500毫秒。
-
第二批任务:
- 阻塞队列中的30个任务进入核心和最大线程池处理。
- 由于15个线程可以同时工作,这30个任务需要两轮:
- 第一轮15个任务,耗时500毫秒。
- 第二轮15个任务,耗时500毫秒。
总耗时:
- 第一批:500毫秒
- 第二批:500毫秒 + 500毫秒
总计:1500毫秒
因此,这批任务执行完成总计需要1500毫秒。
@Test
public void test6() throws InterruptedException {
long s0 = System.currentTimeMillis();
// 创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // 核心线程数
20, // 最大线程数
0L, // 空闲线程存活时间
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(30) // 阻塞队列容量
);
// 提交45个任务
for (int i = 0; i < 45; i++) {
executor.submit(() -> {
try {
// 模拟任务耗时500毫秒
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// 关闭线程池
executor.shutdown();
// 等待所有任务完成
executor.awaitTermination(10, TimeUnit.SECONDS);
System.out.println("所有任务完成: " + (System.currentTimeMillis() - s0));
}
运行结果:
所有任务完成: 1534