美文网首页
线程池任务执行逻辑思考

线程池任务执行逻辑思考

作者: wyfwo | 来源:发表于2019-11-12 19:59 被阅读0次

    在理解线程池的执行逻辑的时候,有关于是先提交入队列还是先创建非核心线程的时候总会混淆。先看下实际的逻辑,盗图(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密集型可以优化。

    相关文章

      网友评论

          本文标题:线程池任务执行逻辑思考

          本文链接:https://www.haomeiwen.com/subject/fboqictx.html