如何解决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,running=2
Running 3
poolSize=3,running=3
Running 4
poolSize=4,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。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。