【趣味题】【线程池】线程池调度

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  小结

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

posted @ 2024-07-18 08:24  酷酷-  阅读(35)  评论(0)    收藏  举报