java ThreadPoolExecutor#getPoolSize()与ThreadPoolExecutor#getActiveCount()有什么区别
我一直在玩ThreadPoolExecutor
。我需要一个返回当前正在运行的线程数的方法。所以我决定使用ThreadPoolExecutor#getActiveCount
然而,当我测试我的方法时,我注意到一些有趣的事情:ThreadPoolExecutor#getActiveCount
总是等于ThreadPoolExecutor#getPoolSize
下面是复制它的示例代码:
class ExecutorTest {
private ThreadPoolExecutor executor;
ExecutorTest() {
executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
}
@Test
void test() {
executor.execute(makeRunnable(100, "1"));
printExecutorState();
executor.execute(makeRunnable(100, "2"));
printExecutorState();
executor.execute(makeRunnable(100, "3"));
printExecutorState();
executor.execute(makeRunnable(100, "4"));
printExecutorState();
System.out.println("==Changing thread core&max pool size==");
executor.setCorePoolSize(2);
executor.setMaximumPoolSize(2);
printExecutorState();
assertThat(executor.getMaximumPoolSize()).isEqualTo(2);
assertThat(executor.getActiveCount()).isEqualTo(4);
}
private Runnable makeRunnable(long workTime, String name) {
return () -> {
long startTime = System.currentTimeMillis();
System.out.println("Running " + name);
while (System.currentTimeMillis() - startTime < workTime) {
}
System.out.println("Exited " + name);
};
}
private void printExecutorState() {
int poolSize = executor.getPoolSize();
int corePoolSize = executor.getCorePoolSize();
int maxPoolSize = executor.getMaximumPoolSize();
int running = executor.getActiveCount();
String currentState = String.format(
"poolSize=%d, corePoolSize=%d, maxPoolSize=%d, running=%d",
poolSize,
corePoolSize,
maxPoolSize,
running
);
System.out.println(currentState);
}
}
它打印以下内容:
Running 1
poolSize=1, corePoolSize=10, maxPoolSize=10, running=1
Running 2
poolSize=2, corePoolSize=10, maxPoolSize=10, running=2
Running 3
poolSize=3, corePoolSize=10, maxPoolSize=10, running=3
Running 4
poolSize=4, corePoolSize=10, maxPoolSize=10, running=4
==Changing thread core&max pool size==
poolSize=4, corePoolSize=2, maxPoolSize=2, running=4
现在的问题是,这些方法之间有什么区别使用ThreadPoolExecutor#getPoolSize
检索正在运行的线程数有意义吗
# 1 楼答案
如果您只需查看javadoc中的函数,就可以得到不同的结果:
池中未执行任何任务的线程将包含在getPoolSize()中,但不包含在getActiveCount()中。在初始代码中,您创建了池大小为10的线程池,但提交了4个任务。因此,池大小为10,活动计数为4。因此,使用
ThreadPoolExecutor#getPoolSize
检索正在运行的线程数是错误的。它只给出创建的线程数,活动运行的线程数由活动计数给出在您的用例中,请注意,即使将最大池大小减少到2,池大小仍然是4。因此,发生的是4个线程正在执行4个任务
完成任务的前两个线程将终止。此时,池大小将减少到2,活动池大小仍将为2(其他正在进行的任务)
当其他两个线程完成任务时,池大小将保持为2(核心池大小),但活动将恢复为0,因为没有任务正在运行