美文网首页
Java线程池

Java线程池

作者: M_lear | 来源:发表于2022-02-27 19:58 被阅读0次

    核心参数

    5个核心参数:

    1. 核心线程数
    2. 最大线程数
    3. 允许线程空闲的时间(获取任务时,阻塞在阻塞队列上的时间)
    4. 空闲时间的单位
    5. 保存Runnable任务的阻塞队列

    Worker

    Worker是线程池的内部类。包装了一个线程来不断的执行任务。

    1. 它实现了Runnable,内部线程start后,执行的就是Worker本身的run方法。
    2. 它继承了AQS,实现了一个不可重入的独占锁,执行任务期间加锁。线程池可以通过tryLock来判断Worker是不是正在执行任务。

    提交任务流程

    线程池提交任务的流程:

    1. 任务过来后,先创建核心线程执行任务(作为Worker的firstTask执行)。
    2. 核心线程数达到设置的限制后,把任务offer进阻塞队列。
    3. 阻塞队列满后,继续创建线程执行任务(firstTask)。
    4. 如果线程数达到最大线程数,则执行对任务的拒绝策略。

    每个Worker执行完firstTask后,会不断的从阻塞队列take或poll任务来执行。

    空闲线程是如何自我回收的?

    线程池使用一个HashSet来持有Workers的引用,需要线程回收时,从HashSet中移除Worker的引用即可。

    自我回收的过程:

    1. Worker在getTask时,会判断【是否回收核心线程】或者【线程数大于核心线程数】。
    2. 如果条件成立,则会调用限时等待的poll方法去获取任务。
    3. 如果超时,没获取到任务。【就会跳出获取任务,执行任务的循环】,来到线程回收的逻辑。
    4. 线程回收,就是把HashSet中的Worker移除,最后让Worker等待GC就行了。

    核心就是【限时等待的poll去阻塞队列获取任务】。

    shutdown和shutdownNow

    两者的区别主要在:

    1. 线程中断上。——中断空闲线程和中断所有线程的区别。
    2. 线程池是否处理阻塞队列中的剩余任务。——处理和不处理的区别。

    shutdown
    shutdown将线程池状态置为SHUTDOWN,【中断】并回收所有的【空闲线程】(通过调用Worker的tryLock判断是否空闲)。【允许线程池继续处理阻塞队列里的剩余任务。】

    所谓“空闲线程”,指的是阻塞在获取任务上的线程。

    线程池状态变成SHUTDOWN后,不再接受新提交的任务,而剩余线程也会在处理完阻塞队列中的剩余任务后被回收。

    shutdownNow
    shutdownNow将线程池状态置为STOP,中断所有线程,清空阻塞队列,【并返回阻塞队列中未处理的任务。】

    线程池状态变成STOP后,同样不再接受新提交的任务。空闲线程被中断后会被立即回收。正在执行任务的线程,如果不看线程的中断标志,会在任务执行结束后被回收。


    一旦调用shutdown或shutdownNow后,线程池最终一定会变为TERMINATED。

    因为在回收每一个线程时,都会调用tryTerminate,判断线程池当前是不是RUNNING态,是否还有其他线程,阻塞队列里是否还有任务。如果都不成立,就会把线程池置为TERMINATED态。

    相关文章

      网友评论

          本文标题:Java线程池

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