能谈谈您具体是怎么管理您的团队成员么?(如何管理调度线程执行)我的管理方式主要是依靠以下几个宝物:
- 状态控制器ctl:用于管理线程池状态和工作者线程个数
- 线程池大小配置corePoolSize和maximumPoolSize:决定了最大能运行多少线程
- 阻塞队列workQueue:当无空闲线程时,暂存在阻塞队列,等待poll出执行
怎么去判断大家什么时候是休息状态,什么时候是工作状态呢;这就靠我的状态控制器ctl,它包含两部分:
- 线程池状态runState:通过这个状态我就能知道什么时候能分配任务,什么时候该下班休息
- 工作者线程个数: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()方法执行完成
状态转换过程为:
- RUNNING -> SHUTDOWN:shutdown()方法被调用时
- (RUNNING or SHUTDOWN) -> STOP:shutdownNow()方法被调用时
- SHUTDOWN -> TIDYING:当workQueue为空且线程池的运行线程为0时
- STOP -> TIDYING:当线程池的运行线程为0时
- TIDYING -> TERMINATED:当terminated()方法执行完成
文章插图
线程调度
整个线程调度以来上述几个法宝:线程池大小、阻塞队列和状态控制器,具体思路如下:
- 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
- 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;
- 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;
- 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会交由RejectedExecutionHandler来处理
文章插图
下面让我们看看具体实现:
文章插图
addWorker:创建一个新的Worker用于执行Runnable
文章插图
文章插图
Worker的run方法实际调用的是ThreadPoolExecutor#runWorker方法:如果工作者本身带有task则执行,否则会从阻塞队列workQueue中poll中一个task进行执行
文章插图
推荐阅读
- Java 分布式系统如何实现session共享?
- 重学之JavaScript HTML Element 常用API解析
- Java 编写基于 Netty 的 RPC 框架
- 特斯拉Model 3申报图 国产Model 3将搭载磷酸铁锂电池
- 为什么iPhone电池寿命低于80%后,就建议及时更换电池?
- 手机充电“一夜不拔”,对电池到底有没有坏处呢?
- 前端:html+css+javascript 手把手教大家编写贪吃蛇小游戏
- 架构选型之Nodejs与Java
- 如何简单理解 JavaScript 的 Async 和 Await?
- Worker基础知识