0
点赞
收藏
分享

微信扫一扫

实例讲解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线程池任务执行过程_线程池

 

问题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线程池任务执行过程_任务队列_02

 

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

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

 

问题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线程池任务执行过程_javascript_04

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

 

拒绝策略

关于拒绝策略可以参考之前的文章

总结

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

 

举报

相关推荐

0 条评论