ThreadPoolExecutor#getPoolSize() vs ThreadPoolExecutor#getActiveCount() 有什么区别
ThreadPoolExecutor#getPoolSize() vs ThreadPoolExecutor#getActiveCount() what is the difference
我一直在玩ThreadPoolExecutor
。我需要一个 returns 当前线程数 运行 的方法。所以我决定使用 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
检索运行线程的数量是否有意义?
如果您只是查看函数的 javadoc,您就会有所不同:
/**
* Returns the current number of threads in the pool.
*
* @return the number of threads
*/
public int getPoolSize()
/**
* Returns the approximate number of threads that are actively
* executing tasks.
*
* @return the number of threads
*/
public int getActiveCount()
池中未执行任何任务的线程将包含在 getPoolSize() 中,但不包含在 getActiveCount() 中。在您的初始代码中,您创建了池大小为 10 的线程池,但提交了 4 个任务。因此池大小为 10,活动计数为 4。因此使用 ThreadPoolExecutor#getPoolSize
检索 运行 线程数是 错误的 。它只是给你创建的线程数,活跃的线程数 运行 由活跃计数给出。
在您的用例中,请注意即使将最大池大小减少到 2 后池大小仍然是 4。所以发生的情况是 4 个线程正在执行 4 个任务。
前两个完成任务的线程将终止。届时,池大小将减少到 2,活动仍将是 2(其他任务正在进行中)。
当其他两个线程完成任务时,池大小将保持为 2(核心池大小),但活动将恢复为 0,因为没有任务 运行。
我一直在玩ThreadPoolExecutor
。我需要一个 returns 当前线程数 运行 的方法。所以我决定使用 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
检索运行线程的数量是否有意义?
如果您只是查看函数的 javadoc,您就会有所不同:
/**
* Returns the current number of threads in the pool.
*
* @return the number of threads
*/
public int getPoolSize()
/**
* Returns the approximate number of threads that are actively
* executing tasks.
*
* @return the number of threads
*/
public int getActiveCount()
池中未执行任何任务的线程将包含在 getPoolSize() 中,但不包含在 getActiveCount() 中。在您的初始代码中,您创建了池大小为 10 的线程池,但提交了 4 个任务。因此池大小为 10,活动计数为 4。因此使用 ThreadPoolExecutor#getPoolSize
检索 运行 线程数是 错误的 。它只是给你创建的线程数,活跃的线程数 运行 由活跃计数给出。
在您的用例中,请注意即使将最大池大小减少到 2 后池大小仍然是 4。所以发生的情况是 4 个线程正在执行 4 个任务。
前两个完成任务的线程将终止。届时,池大小将减少到 2,活动仍将是 2(其他任务正在进行中)。
当其他两个线程完成任务时,池大小将保持为 2(核心池大小),但活动将恢复为 0,因为没有任务 运行。