美文网首页
线程池-2

线程池-2

作者: 01010100 | 来源:发表于2018-04-20 11:28 被阅读11次

2.3 ThreadPoolExecutor核心源码:

execute:提交任务

三步曲:

活动线程 < corePoolSize,直接创建新的线程;

活动线程>

corePoolSize,加到任务队列当中;

当队列已满且活动线程< maximumPoolSize,创建新线程,否则拒绝任务

关键设计:       

2.3.1 双重校验:在添加队列成功后,还会再次校验线程池是否running状态,若校验失败则从队列移除

2.3.2 若活动线程数量 == 0,添加一个空任务,会重新创建Worker,并且runWorker,真正的目的是runWorker的时候会重新去getTask()即从队列中去获取任务

public void execute(Runnable command) {

int c = ctl.get();

if (workerCountOf(c) < corePoolSize) {             //第一步

       if (addWorker(command,true))

              return;

       c = ctl.get();

}

if (isRunning(c) && workQueue.offer(command)) {  //第二步

       int recheck = ctl.get();

       if (! isRunning(recheck)&& remove(command))       //双重校验

              reject(command);

       else if(workerCountOf(recheck) == 0) //活动线程数量为0

              addWorker(null,false);

}

else if (!addWorker(command, false))  //第三步

       reject(command);

}

其中,一二三步意思都很清晰,关键就是第二步有个双重校验:

加入队列成功之后,再次校验线程池状态是否为running,校验不通过则从队列移除,移除成功则拒绝这个任务。校验不通过这其实是临界情况:即加入队列时线程池状态还是RUNNING而双重校验时线程池已经是SHUTDOWN或STOP等。而如果校验不通过并且从队列中移除任务失败了,则实际意义就是已经添加到队列中了,和校验通过是一样的效果,都是把任务添加到队列中了。此时,再判断线程池的活动线程数,若线程池中活动线程数为0,即线程池中没有活动线程,则addWorker(null,

false)。添加一个任务为null的Worker,目的何在?因为线程池中已经没有活动线程了,利用addWorker新开一个线程,而任务为null时,当前线程会从队列中去获取任务。

具体如下:结合下面的addWorker:addWorker成功会new Worker即新开一个线程并启动,start() -> run() -> runWorker() ,runWorker又干了啥,while (task != null || (task = getTask()) != null),这里就很清楚了,task非空的时候,会直接执行当前task。而若task为空会调用getTask() -> workQueue.poll/

workQueue.take,从队列中去获取,执行完再回到循环中重新到队列拉取。所以添加一个null的task目的就是:当活动线程数为空时,会重新启动线程从队列中不断的获取任务,保证队列中的任务都被执行完。

结合上述的一般线程池为SHUTDOWN时,活动线程数才会为空。所以这里针对场景主要就是:添加队列成功后,突然线程池状态变成SHUTDOWN,线程池不再接受新任务,但是仍要把队列中的任务执行完。是不是感觉设计的很精妙?

相关文章

  • 线程池

    线程池组件 1、线程池管理器(ThreadPoolManager):用于创建并管理线程池 2、工作线程(WorkT...

  • 线程池核心参数

    线程池核心参数 1)corePoolSize(线程池基本大小) 2)maximumPoolSize(线程池最大数量...

  • 线程池学习笔记

    1、线程池的定义 2、Executors创建线程池的方式 3、ThreadPoolExecutor对象 4、线程池...

  • 线程池(3)终止线程池原理

    终止线程池 一、终止线程池方法 1、 shutdown() 安全的终止线程池 2、 shutdownNow() 强...

  • 线程池相关知识

    线程池 1. 什么是线程池 线程的池化,一个线程的容器、集合,包含多个线程 2. 为什么要用线程池 线程对于操作系...

  • 线程池

    1、为什么要使用线程池2、线程池的工作原理3、线程池参数4、阻塞队列5、饱和策略6、向线程池提交任务7、线程池的状...

  • ScheduledThreadPoolExecutor线程池

    1. ScheduledThreadPoolExecutor线程池2. SpringBoot2.X整合定时线程池(...

  • 2019-03-13 自定义连接池

    连接池:即线程池要自定义先要了解线程池模型,即线程池的核心参数1.coresize核心线程池,即运行的线程2.ma...

  • 线程池

    目录: 1.线程池的作用2.线程池的种类3.线程池的使用 线程池的作用: 线程主要是通过控制执行的线程的数量,超出...

  • 线程池总结

    1 第一篇 初识线程池主要讲线程池的好处,线程池的分类,以及线程池的结构图2 第二篇 再识线程池通过线程池的构造函...

网友评论

      本文标题:线程池-2

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