美文网首页美丽的爪哇岛我爱编程
Java线程池如何维护线程对象

Java线程池如何维护线程对象

作者: begonia_rich | 来源:发表于2018-05-27 15:05 被阅读34次

    今天被这个问题整晕了,好好想了一下看了看源码才整清楚,看来以前还是没有理解的深入啊..稍微换个问法就晕了

    线程池的基本流程

    先弄清楚基本流程再去看部分实现细节

    1如果运行的线程少于corePoolSize,则Executor始终首选添加新的线程,而不进行排队.
    2如果运行的线程等于或多于corePoolSize,则 Executor 始终首选将请求加入队列,而不添加新的线程.
    3如果无法将请求加入队列,则创建新的线程,除非创建此线程超出 maximumPoolSize,在这种情况下,任务将被拒绝.

    这个流程一定要记清楚,这是最基本的流程啦

    基本流程实现

    我以JDK1.8中execute方法看看大体编码实现过程(略去部分细节)

    execute方法

    可以看到execute方法就是对上面那三个流程的实现,这里就牵涉到另一个问题了,工作线程是如何工作的.下面继续看addWorker方法(这个方法太长了,我粘贴出来删去了部分)

    addWorker方法

    基本流程相当简单,将当前任务作为firstTask参数丢给Worker对象,然后维护Worker对象的引用,最后start起来Worker线程.

    下面看一下如何维护Worker列表的,就是一个HashSet对象....


    维护Worker的列表

    下面看Worker对象的实现


    Worker对象

    看一下runWorker方法,这就是最后的核心逻辑了


    runWorker

    大体的代码实现细节就是这样的流程了.


    总结

    总结一下实现细节收获

    1线程池如何维护线程对象?

    直接通过HashSet持有,Worker对象是在addWorker方法后被新建一个Thread对象运行(Thread对象start之后并没有直接持有,这个Thread被放到了Worker对象作为一个属性持有了),Worker对象的run方法中自己会去自旋取阻塞队列中的Runnable任务.我们只维护了Worker对象,启动Worker对象的线程就在Worker对象中持有.停止时就是遍历了Worker对象取出线程对象,然后调用停止方法等...

    2如果新增任务时并未达到核心线程池大小,那么新加入的任务是否有可能会被其他Worker线程执行?

    不会,新任务不会进入阻塞队列并且新建Worker线程要求传入FirstTask任务参数,也就是Worker线程会先执行当前加入进来的第一个任务,然后再去阻塞队列获取任务执行.

    3阻塞队列的阻塞如何实现的

    基础的通知等待模型就可以实现.也可以用ReentrantLock和Condition实现(ArrayBlockingQueue和LinkedBlockingQueue都是基于这个实现的),线程池已不关心实现细节了,只要求是个阻塞队列就可以

    其他

    深入细节还是要去看一下源码,理解了细节才可以描述清楚线程池的实现,这里记录一下方便以后迷糊的时候回来理解...也希望能帮助到迷糊的同学....

    相关文章

      网友评论

        本文标题:Java线程池如何维护线程对象

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