Java线程池的管理方法论( 二 )

能谈谈您具体是怎么管理您的团队成员么?(如何管理调度线程执行)
我的管理方式主要是依靠以下几个宝物:
  1. 状态控制器ctl:用于管理线程池状态和工作者线程个数
  2. 线程池大小配置corePoolSize和maximumPoolSize:决定了最大能运行多少线程
  3. 阻塞队列workQueue:当无空闲线程时,暂存在阻塞队列,等待poll出执行
状态控制器ctl
怎么去判断大家什么时候是休息状态,什么时候是工作状态呢;这就靠我的状态控制器ctl,它包含两部分:
  1. 线程池状态runState:通过这个状态我就能知道什么时候能分配任务,什么时候该下班休息
  2. 工作者线程个数:workCount
这里先介绍两个常量和获取这两部分信息的方式:
// 将32位int分割为3和29,前三位用于存储线程池状态,后面的位数表示工作者线程个数int COUNT_BITS = Integer.SIZE - 3; // 工作者线程个数,最大为2^29-1 int CAPACITY = (1 << COUNT_BITS) - 1;/**1. runState:高三位来代表线程池状态,runState2. workCount:表示工作者个数*/int runStateOf(int c) { return c & ~CAPACITY; }int workerCountOf(int c) { return c & CAPACITY; }int ctlOf(int rs, int wc) { return rs | wc; }线程池状态主要有以下几种:
  • RUNNING = -1 << COUNT_BITS:允许接入新的task或处理workQueue中的task
  • SHUTDOWN = 0 << COUNT_BITS:不接受新的task,但是能处理workQueue中的task
  • STOP = 1 << COUNT_BITS:不接受新task,也不处理workQueue中的task,同时还会interrupt当前运行的task
  • TIDYING = 2 << COUNT_BITS:当状态变为TIDYING将会调起terminated()方法:所有task都被中断,workerCount=0;
  • TERMINATED = 3 << COUNT_BITS:terminated()方法执行完成
其中TERMINATED > TIDYING > STOP > SHUTDOWN > RUNNING
状态转换过程为:
  • RUNNING -> SHUTDOWN:shutdown()方法被调用时
  • (RUNNING or SHUTDOWN) -> STOP:shutdownNow()方法被调用时
  • SHUTDOWN -> TIDYING:当workQueue为空且线程池的运行线程为0时
  • STOP -> TIDYING:当线程池的运行线程为0时
  • TIDYING -> TERMINATED:当terminated()方法执行完成
如下图:
Java线程池的管理方法论

文章插图
 
线程调度
整个线程调度以来上述几个法宝:线程池大小、阻塞队列和状态控制器,具体思路如下:
  • 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
  • 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;
  • 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;
  • 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会交由RejectedExecutionHandler来处理
如下图:
Java线程池的管理方法论

文章插图
 
下面让我们看看具体实现:
Java线程池的管理方法论

文章插图
 
addWorker:创建一个新的Worker用于执行Runnable
Java线程池的管理方法论

文章插图
 

Java线程池的管理方法论

文章插图
 
Worker的run方法实际调用的是ThreadPoolExecutor#runWorker方法:如果工作者本身带有task则执行,否则会从阻塞队列workQueue中poll中一个task进行执行
Java线程池的管理方法论

文章插图
 
 




推荐阅读