实例讲解ThreadPoolExecutor线程池任务执行过程

背景

为了方便测试,设置核心线程数(corePoolSize)为2,最大线程数(maximumPoolSize)为3,任务队列长度为3。

构建测试环境

创建一个线程池,任务执行时长通过doSomeThing的sleep时长来决定。


    public static void testThreadPoolExecutor(int listSize) {

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                 2,  5, 10L,
                TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(3));

        if (listSize <= 0){
            return;
        }
        try {
            for (int i = listSize; i > 0; i--) {

                executor.execute(() -> doSomeThing());
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executor.shutdown();
            while (true) {
                if (executor.isTerminated()) {
                    break;
                }
            }
        }


    }

    private static void doSomeThing()  {
        try {
            Thread.sleep(1);
        }catch (Exception e){

        }

    }

问题1

启动线程池,还未提交任务,此时线程池有几个线程?

答:0个,debug可以看出,创建线程池后,并没有往线程池添加线程。

实例讲解ThreadPoolExecutor线程池任务执行过程_第1张图片

 

问题2

提交第一个任务,待第一个任务执行完成之后,再提交第二个任务,此时线程池有几个线程?即在第一个任务执行完成后,提交第二个任务,是否会创建新线程?

答:会创建新线程

源码的注释上写到

When a new task is submitted in method {@link #execute(Runnable)},
* and fewer than corePoolSize threads are running, a new thread is
* created to handle the request, even if other worker threads are
* idle

线程数小于核心线程数时,即使其他线程是空闲的,也会创建新的线程

even if other worker threads are idle

将doSomeThing的sleep时长设置为1

debug调试显示,即使前一个任务执行完了,再次提交任务,依旧会创建新的线程

实例讲解ThreadPoolExecutor线程池任务执行过程_第2张图片

 

源码中,只判断了当前线程数是否小于核心线程数,并没有校验上一个线程是否空闲状态

实例讲解ThreadPoolExecutor线程池任务执行过程_第3张图片

 

问题3

同时提交两个任务,执行时间都超长,此时再提交一个任务,是创建新线程来执行还是将任务提交至任务队列?

将doSomeThing的sleep时长设置为无限大

答:将任务提交至队列 ,直至队列满了,才会继续创建新线程。

源码注释中写道

If there are more than corePoolSize but less than
* maximumPoolSize threads running, a new thread will be created only
* if the queue is full.

如果线程大约核心线程数,且小与最大线程数是,只有队列满了才会创建新的线程

only if the queue is full.

实例讲解ThreadPoolExecutor线程池任务执行过程_第4张图片

实例讲解ThreadPoolExecutor线程池任务执行过程_第5张图片

 

拒绝策略

关于拒绝策略可以参考之前的文章icon-default.png?t=M5H6https://blog.csdn.net/leisure_life/article/details/124794155

总结

实例讲解ThreadPoolExecutor线程池任务执行过程_第6张图片

 

你可能感兴趣的:(Java基础,java,线程池,多线程)