通过链接以下链接得知,分为高低位对应
- workerCount: 当前的工作线程数量,低位
- runState:线程池的状态,高位
https://www.jianshu.com/p/9a200a89bd64
源码如下
// ctl 变量是 int 类型,对应比特位是32位,按照高低位对运行状态和线程总数分别进行存储
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// 线程总数用到的 int 类型总位数
private static final int COUNT_BITS = Integer.SIZE - 3;
// 最大线程总数,即 2^29-1=536,870,911,5亿多
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
// 运行状态 runState,通过 runStateOf() 获取到对应的变量值
// RUNNING 对应 -536870912
private static final int RUNNING = -1 << COUNT_BITS;
// SHUTDOWN 对应 0
private static final int SHUTDOWN = 0 << COUNT_BITS;
// STOP 对应 536870912
private static final int STOP = 1 << COUNT_BITS;
// TIDYING 对应 1073741824
private static final int TIDYING = 2 << COUNT_BITS;
// TERMINATED 对应 1610612736
private static final int TERMINATED = 3 << COUNT_BITS;
其中,线程池运行状态值通过位移计算得出
具体值如下
状态名 | 状态值 |
RUNNING | -536870912 |
SHUTDOWN | 0 |
STOP | 536870912 |
TIDYING | 1073741824 |
TERMINATED | 1610612736 |
通过源码注释得知,CAPACITY 的值为 2^29-1,即 536870911,五亿多。
// 获取运行状态 runState,CAPACITY 取反和 ctl 按位与
private static int runStateOf(int c) { return c & ~CAPACITY; }
// 获取线程数量 workerCount,CAPACITY 和 ctl 按位与
private static int workerCountOf(int c) { return c & CAPACITY; }
// 运行状态和线程数量取或,用于设置运行状态
private static int ctlOf(int rs, int wc) { return rs | wc; }
workerCountOf 的计算逻辑
其中 CAPACITY 的值为固定值,将 ctl 变量的值与 CAPACITY 按位与,由于用于总数计算的数据位只有29位,按位与只返回都为1的数据,综合下来返回实际的 worker 总数。
runStateOf 的计算逻辑
将 CAPACITY 的值取反,则实际值为 0,将对应的值与 ctl 的值按位与,由于数据只返回都为1的数据且状态为高位,即只返回高位的状态数据。
public 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.
*
* 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.
*
* 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;
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)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
从 execute 中得知,线程创建最终是通过 addWorker() 创建了 Worker 对象,继承了 aqs,实现了
Runnable 接口。
如果线程数量小于核心线程总数,添加到核心线程中
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
通过 compareAndIncrementWorkerCount() 实现了对 ctl 变量的累加
/**
* Attempts to CAS-increment the workerCount field of ctl.
*/
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
由 addWorker() 代码得出,有两种情况不处理线程添加
有两种情况
1、如果线程数 workerCount 大于线程最大值,不处理
2、分两种情况
当前线程为核心线程,取核心线程数量
当前线程为非核心线程,取非核心线程数量
workerCount 大于等于线程数量,不处理,即 workerCount 小于线程数量才处理
即,工作线程数量不会大于最大线程池的数量。
满足处理线程的要求将 ctl 中 workerCount 自增1
到这里,任何提交的线程任务最终都是以 Worker 的形式来执行。
/**
* Returns the approximate number of threads that are actively
* executing tasks.
*
* @return the number of threads
*/
public int getActiveCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int n = 0;
for (Worker w : workers)
if (w.isLocked())
++n;
return n;
} finally {
mainLock.unlock();
}
}
通过源码得知,获取活动执行任务的大致总数,是获取了正在锁定的 Worker 的数量。
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
在执行任务的时候会加锁,为了线程池中断。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestThread2 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
int corePoolSize = Runtime.getRuntime().availableProcessors();
int maximumPoolSize = corePoolSize << 1;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(10);
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 1, TimeUnit.SECONDS, workQueue);
for (int i = 1;i <= 1000; i++) {
executor.execute(new Thread());
System.out.println(executor);
}
}
}
执行结果
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 2, active threads = 1, queued tasks = 0, completed tasks = 1]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 3, active threads = 1, queued tasks = 0, completed tasks = 1]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 4, active threads = 1, queued tasks = 0, completed tasks = 3]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 5, active threads = 2, queued tasks = 0, completed tasks = 3]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 6, active threads = 2, queued tasks = 0, completed tasks = 4]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 7, active threads = 3, queued tasks = 0, completed tasks = 4]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 8, active threads = 4, queued tasks = 0, completed tasks = 4]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 9, active threads = 3, queued tasks = 0, completed tasks = 6]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 10, active threads = 3, queued tasks = 0, completed tasks = 7]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 11, active threads = 2, queued tasks = 0, completed tasks = 9]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 12, active threads = 2, queued tasks = 0, completed tasks = 10]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 13, active threads = 1, queued tasks = 0, completed tasks = 12]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 14, active threads = 1, queued tasks = 0, completed tasks = 13]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 15, active threads = 2, queued tasks = 0, completed tasks = 13]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 2, queued tasks = 0, completed tasks = 14]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 2, queued tasks = 1, completed tasks = 14]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 1, queued tasks = 0, completed tasks = 17]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 1, completed tasks = 18]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 1, completed tasks = 19]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 2, completed tasks = 19]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 3, completed tasks = 19]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 1, completed tasks = 22]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 0, completed tasks = 24]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 1, completed tasks = 24]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 0, completed tasks = 25]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 0, completed tasks = 26]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 0, completed tasks = 27]
java.util.concurrent.ThreadPoolExecutor@443b7951[Running, pool size = 16, active threads = 0, queued tasks = 0, completed tasks = 28]
...省略
执行结果参数含义如下
pool size
线程池中所有 Worker 线程的数量
active threads
正在执行的 Worker 数量
queued tasks
队列中的任务数量
completed tasks
已经完成任务数量
其中,toString() 中 active threads 对应的变量 nactive 的值和 getActiveCount() 逻辑一致,即通过 getActiveCount() 可以获取当期活跃的工作线程。任务在执行的时候会加锁,通过锁的状态可以判断当前任务是否活跃状态。
工作线程保存在 workers 中
/**
* Set containing all worker threads in pool. Accessed only when
* holding mainLock.
*/
private final HashSet<Worker> workers = new HashSet<Worker>();
参考链接