英文:
ThreadPoolExecutor#getPoolSize() vs ThreadPoolExecutor#getActiveCount() what is the difference
问题
ThreadPoolExecutor#getPoolSize
and ThreadPoolExecutor#getActiveCount
are two methods in Java's ThreadPoolExecutor
class used for managing and monitoring thread pools. Here's the difference between them:
-
ThreadPoolExecutor#getPoolSize
:- This method returns the current size of the thread pool, which is the total number of threads that have been created and are currently in the pool.
- It includes both active (running) threads and idle threads waiting to execute tasks.
- It doesn't give you the exact count of currently running threads; it gives you the total pool size, including those waiting for tasks.
-
ThreadPoolExecutor#getActiveCount
:- This method returns the approximate number of threads that are actively executing tasks.
- It provides a count of the threads that are currently running tasks and excludes idle threads.
- It is designed to give you a more accurate count of the currently running threads.
In your code and output, you can see that ThreadPoolExecutor#getPoolSize
gives you the total pool size, which includes both running and idle threads, whereas ThreadPoolExecutor#getActiveCount
gives you the count of actively running threads.
For most cases where you need to know the number of running threads, it makes more sense to use ThreadPoolExecutor#getActiveCount
because it provides a more accurate count of currently executing threads. Using ThreadPoolExecutor#getPoolSize
may not accurately reflect the number of active threads, especially if there are idle threads in the pool.
英文:
I've been playing with ThreadPoolExecutor
. I needed a method that returns the number of threads which are currently running. So I decided to use ThreadPoolExecutor#getActiveCount
.
However, when I was testing my methods I noticed something interesting: ThreadPoolExecutor#getActiveCount
is always equal to ThreadPoolExecutor#getPoolSize
.
Here is a sample code to reproduce it:
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);
}
}
It prints the following:
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
Now the question is what is the difference between these methods? Does it make sense to use ThreadPoolExecutor#getPoolSize
to retrieve number of running threads?
答案1
得分: 1
以下是翻译好的部分:
"你只需查看函数的javadoc,就可以明显看出差异:
/**
* 返回池中当前线程数。
*
* @return 线程数
*/
public int getPoolSize()
/**
* 返回活动执行任务的线程数的近似值。
*
* @return 线程数
*/
public int getActiveCount()
在池中并且没有执行任何任务的线程将包括在getPoolSize()中,但不包括在getActiveCount()中。在你的初始代码中,你创建了池大小为10的线程池,但提交了4个任务。因此,池大小为10,活动计数为4。因此,使用ThreadPoolExecutor#getPoolSize
来检索运行线程的数量是错误的。它只会给你创建的线程数量,实际运行线程的数量由活动计数给出。
在你的用例中,请注意即使将最大池大小减小到2,池大小仍然为4。所以发生的情况是4个线程正在执行4个任务。
首先完成其任务的前两个线程将终止。在那时,池大小将减小到2,但仍然是2(其他任务正在进行中)。
当其他两个线程完成其任务时,池大小将保持为2(核心池大小),但活动计数将恢复为0,因为没有任务在运行。"
英文:
You can get the difference if you simply look at javadoc for the functions:
/**
* 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()
A thread that is in the pool and not executing any task will be included getPoolSize() but not in getActiveCount(). In your initial code, you created thread pool with pool size 10, but submitted 4 tasks. Hence pool size was 10 and active count was 4. So use of ThreadPoolExecutor#getPoolSize
to retrieve number of running threads is wrong. It just gives you the number of threads created, the number of actively running threads is given by active count.
In your use case, notice how the pool size is still 4 even after reducing max pool size to 2. So what is happening is 4 threads are executing 4 tasks.
First two threads that complete their task will terminate. At that point, pool size will be reduced to 2 and active will still be 2 (other tasks in progress).
When other two threads complete their task, pool size will remain 2 (core pool size) but active will revert to 0 since no tasks are running.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论