带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(2)https://developer.aliyun.com/article/1340067?groupCode=taobaotech
线程池任务调度机制
线程池提交一个任务时任务调度的主要步骤如下:
- 当线程池里存活的核心线程数小于corePoolSize核心线程数参数的值时,线程池会创建一个核心线程去处理提交的任务;
- 如果线程池核心线程数已满,即线程数已经等于corePoolSize,新提交的任务会被尝试放进任务队列work- Queue中等待执行;
- 当线程池里面存活的线程数已经等于corePoolSize了,且任务队列workQueue已满,再判断当前线程数是否已 达到maximumPoolSize,即最大线程数是否已满,如果没到达,创建一个非核心线程执行提交的任务;
- 如果当前的线程数已达到了maximumPoolSize,还有新的任务提交过来时,执行拒绝策略进行处理。
核心代码如下:
1public void execute(Runnable command) { if (command == null) throw new NullPointerException(); /* * Proceed in 3 steps: * * 1. If fewer than corePoolSize threads are running, try to * start a new thread with the given command as its first * task. The call to addWorker atomically checks runState and * workerCount, and so prevents false alarms that would add * threads when it shouldn't, by returning false. 12 * * 2. If a task can be successfully queued, then we still need * to double-check whether we should have added a thread * (because existing ones died since last checking) or that * the pool shut down since entry into this method. So we * recheck state and if necessary roll back the enqueuing if * stopped, or start a new thread if there are none. 19 * * 3. If we cannot queue task, then we try to add a new * thread. If it fails, we know we are shut down or saturated * and so reject the task. */ int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return;
28 |
|
c = ctl.get(); |
29 |
|
} |
30 |
|
if (isRunning(c) && workQueue.offer(command)) { |
31 |
|
int recheck = ctl.get(); |
32 |
|
if (! isRunning(recheck) && remove(command)) |
33 |
|
reject(command); |
34 |
|
else if (workerCountOf(recheck) == 0) |
35 |
|
addWorker(null, false); |
36 |
|
} |
37 |
|
else if (!addWorker(command, false)) |
38 |
|
reject(command); |
39 |
} |
|
带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(4)https://developer.aliyun.com/article/1340065?groupCode=taobaotech