【趣味题】【线程池】线程池调度
1 前言
一个线程池的核心线程数为10个,最大线程数为20个,阻塞队列的容量为30。现在提交45个 任务,每个任务的耗时为500毫秒。 请问:这批任务执行完成总计需要多少时间?注:忽略线程创建、调度的耗时。
2 测试
先不写代码,按照线程池的一个任务处理过程来看的话,总共45个任务,10个核心跑10个任务,30个任务进入队列,还剩5个任务再创建了5个线程去跑,所以第一次15个线程跑15个任务,耗时500毫秒,第二次15个线程从队列捞15个任务继续耗时500毫秒,第三次还是捞15个任务耗时500毫秒,所以大概算下来应该是1500毫秒,也就是1.5秒应该。
我们按照题目意思,用代码表示一下:
/** * @author kuku * @description */ public class PoolTest { /** * 按题目要求 * 创建线程池 */ private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor( // 10个核心 10, // 最大20个 20, 1L, TimeUnit.SECONDS, // 队列30 new ArrayBlockingQueue<>(30) ); public static void main(String[] args) { int taskSum = 45; // 把任务往线程池里边放 for (int i = 0; i < taskSum; i++) { EXECUTOR.execute(() -> { try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } }); } } }
按照题目的意思写是写完了,那么怎么统计耗时呢?看看这样写行不行:
/** * @author kuku * @description */ public class PoolTest { /** * 按题目要求 * 创建线程池 */ private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor( // 10个核心 10, // 最大20个 20, 1L, TimeUnit.SECONDS, // 队列30 new ArrayBlockingQueue<>(30) ); public static void main(String[] args) { int taskSum = 45; // 存放一下所有的任务 List<Future> list = Lists.newArrayListWithCapacity(taskSum); // 计时器并开始 StopWatch stopWatch = new StopWatch(); stopWatch.start(); // 把任务往线程池里边放 for (int i = 0; i < taskSum; i++) { // 把每个任务都放进集合中 Future<?> future = EXECUTOR.submit(() -> { try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } }); list.add(future); } // 遍历所有的任务,是否都完成了么 list.forEach(i -> { try { i.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }); // 到这里说明任务都执行了 stopWatch.stop(); // 打印下耗时 System.out.println(stopWatch.getTotalTimeMillis()); } }
执行结果:大致跟计算的没错 1.5秒

3 小结
有理解不对的地方欢迎指正哈。

浙公网安备 33010602011771号