Java线程池ThreadPoolExecutor主要参数和execute详解

更新时间:2023-05-06 20:34:22 阅读: 评论:0

Java线程池ThreadPoolExecutor主要参数和execute详解本⽂针对对ThreadPoolExecutor有⼀定了解的⼈群,本⽂的讨论暂不考虑线程的销毁
public class ThreadPoolExecutor extends AbstractExecutorService {
private volatile int corePoolSize;//核⼼线程数
private volatile int maximumPoolSize;//最⼤线程数
private final BlockingQueue<Runnable> workQueue;//⼯作队列
}
上⾯我们列出了线程池主要的三个参数,表⾯意思我们都明⽩。但是下⾯⼏个问题,我们都想过吗?
1、线程池在什么情况下将线程数增加到核⼼线程数?
2、线程池在什么情况下将线程数增加到最⼤线程数?
3、线程池在什么情况下会将新执⾏的线程放⼊到⼯作队列呢?
4、待执⾏线程⼤于核⼼线程数的时候,是先将线程数增加到最⼤线程数还是现将线程放到⼯作队列呢?
只有回答了了上⾯的疑问,我们才能更⾼效的利⽤线程,这些疑问我们都可以在execute()⽅法中得到解答。
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ();
if (! isRunning(recheck) && remove(command))
reject(command);
el if (workerCountOf(recheck) == 0)
addWorker(null, fal);
}
el if (!addWorker(command, fal))
reject(command);
}
execute中有三个if条件,我们明⽩了这三个if条件表⽰的意义,上⾯四个问题也就得到了解答。
解释三个if之前我现将这⾥⾯涉及的主要⽅法做个解释
workerCountOf(c):获取当前正在运⾏的线程数,此⽅法是通过位运算取与得出,值得我们借鉴,但在此处我不再展开讨论
addWorker(Runnable firstTask, boolean core):增加⼀个⼯作线程并执⾏,这⾥我们说下第⼆个参数,查看addWorker代码,在下⾯代码引⽤了core
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return fal;
由上⾯的,代码得知,
core=true时,判断当前⼯作线程数是否⼤于等于核⼼线程数,如果⼤于则添加失败。
core=fal时,判断当前⼯作线程数是否⼤于最⼤线程数,如果⼤于则添加失败
1、主要⽅法都解释完了,先说第⼀个if
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ();
}
通过上⾯的代码,执⾏execute()时,如果当前执⾏线程数⼩于corePoolSize,就会增加⼯作线程。通过if判断我们的第⼀个问题
1、线程池在什么情况下将线程数增加到核⼼线程数?
也就得到了解答:在⼯作线程数⼩于核⼼线数,只要有新的线程执⾏线程池就会增加⼯作线程直⾄“⼯作线程数=核⼼线程数”
2、如果⼯作线程数>核⼼线程数,将执⾏我们的第⼆个if块
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ();
if (! isRunning(recheck) && remove(command))
reject(command);
el if (workerCountOf(recheck) == 0)
addWorker(null, fal);
}
第⼆个if的核⼼代码就是 isRunning(c) && workQueue.offer(command):如果线程池状态是running,则将新增的command添加到⼯作队列⾥。这个if条件⾥⾯的代码是做状态的⼆次校验,我在这不再讨论。
通过第⼆个if条件,下⾯这个问题答案就得到了解答
3、线程池在什么情况下会将新执⾏的线程放⼊到⼯作队列呢?
答:在线程池⼯作线程数>=corePoolSize时,新执⾏的线程会被放到⼯作队列
3、我们认为线程池的状态始终是running,那么如果workQueue.offer(command)为fal(表⽰队列已经满了),则会进⼊到第三个if 块
el if (!addWorker(command, fal))
reject(command);
此处的核⼼代码是:!addWorker(command, fal)。第⼆个参数是fal,也就是说只要⼯作线程数⼩于最⼤线程数,则会添加⼯作线程数直⾄线程池的⼯作线程数等于最⼤线程数。
通过第三个if条件,我们剩下的两个问题也得到了解答
2、线程池在什么情况下将线程数增加到最⼤线程数?
答:⼯作线程>=corePoolSize,并且workQueue满的时候,有新的线程就会增加线程池的⼯作线程,直⾄增加到maximumPoolSize
4、待执⾏线程⼤于核⼼线程数的时候,是先将线程数增加到最⼤线程数还是现将线程放到⼯作队列呢?
答:上⾯三个问题都解答完了,那么这个问题也就明了了。是现将线程放⼊⼯作队列,如果⼯作队列满了才开始继续增加线程,直到⼯作线程等于最⼤线程数。
总结:
线程池增加⼯作线程的顺序
corePoolSize->workQueue->maximumPoolSize
这样的话我们在创建线程池的时候需要注意:
corePoolSize<maximumPoolSize时,如果workQueue是⽆限序列的时候,那么线程池的线程数永远⽆法增加到maximumPoolSize,那么maximumPoolSize也就不⽣效了。

本文发布于:2023-05-06 20:34:22,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/98418.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   增加   代码
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图