线程池任务执行逻辑思考

2019-11-12  本文已影响0人  wyfwo

在理解线程池的执行逻辑的时候,有关于是先提交入队列还是先创建非核心线程的时候总会混淆。先看下实际的逻辑,盗图(https://mp.weixin.qq.com/s/Nv1ITA_i8Q64XLj7nC0yCg):

线程池提交任务时的执行逻辑

实际情况是:在核心线程数已满的情况下,如果任务缓冲队列已满才会创建非核心线程;如果队列未满时,任务将会提交入队列排队。

对比下如果优先创建非核心线程会有啥问题,权衡利弊:

优先入队列的优点:

1.  池中的线程循环取队列里的任务,如果队列没满就创建非核心线程,会出现队列为空就创建非核心线程的情况,将导致反复创建和销毁非核心线程的开销;

2. 队列空间将大概率浪费,只有当最大线程数都处理不完的任务量时才有可能利用这些空间

3. 待完善~

优先入队列的缺点:

1. 任务可能有少许延迟(在队列排队呢)

2. 会出现插队现象,队列满了时,创建的非核心线程直接执行了后到来的任务;

3. 待完善~

综合权衡的话,少许延迟可以接受,任务之间通常没有先后依赖,优先入队列性能开销及逻辑更加合理。


补充:

jdk原生的线程池确实完善(如上图的执行逻辑),但是这种比较适合cpu密集型的任务,如果是IO密集型的话,线程不一定都在运行,很可能是阻塞的,这样的效率会比较底下;所以针对IO密集型的任务,还是优先创建线程比较靠谱。

所以可以看到tomcat(网络IO型)在jdk原生线程池的基础上做了扩展:在向队列添加任务时,判断待执行的任务数(原子的计数变量:submittedCount)大于当前线程数,则直接返回false,优先创建非核心线程了;参考

或者可以使用jdk的keepAliveTime使非核心线程永久不失效,不过可能浪费资源~

总结:jdk原生线程池执行逻辑是否合理,it depends! 如果是cpu密集型,合理;IO密集型可以优化。

上一篇下一篇

猜你喜欢

热点阅读