为什么总是 threadPoolExecutor.getActiveCount() <= maximumPoolSize/2?
Why is always threadPoolExecutor.getActiveCount() <= maximumPoolSize/2?
我们有一个任务队列,它的初始化看起来像:
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(maximumPoolSize, maximumPoolSize, 50000L, TimeUnit.MILLISECONDS, queue);
maximumPoolSize
的值为200。队列工作时得到大量线程(超过一千),但threadPoolExecutor.getActiveCount()
返回的值总是小于或等于100 . 例如,值 threadPoolExecutor.getActiveCount()
和 queue.size()
记录如下:
logger.debug("Active threads: " + threadPoolExecutor.getActiveCount() + ". The queue has " + queue.size() + " threads.");
结果我们得到以下日志:
Active threads: 1. The queue has 0 threads.
Active threads: 2. The queue has 0 threads.
Active threads: 3. The queue has 0 threads.
Active threads: 4. The queue has 0 threads.
Active threads: 5. The queue has 0 threads.
...
Active threads: 86. The queue has 0 threads.
Active threads: 87. The queue has 1 threads.
Active threads: 88. The queue has 1 threads.
Active threads: 89. The queue has 1 threads.
Active threads: 90. The queue has 1 threads.
...
Active threads: 99. The queue has 1 threads.
Active threads: 100. The queue has 1 threads.
Active threads: 100. The queue has 2 threads.
Active threads: 100. The queue has 3 threads.
Active threads: 100. The queue has 4 threads.
...
Active threads: 100. The queue has 1874 threads.
Active threads: 100. The queue has 1875 threads.
Active threads: 100. The queue has 1876 threads.
Active threads: 100. The queue has 1877 threads.
Active threads: 100. The queue has 1878 threads.
Active threads: 100. The queue has 1879 threads.
Active threads: 100. The queue has 1880 threads.
Active threads: 100. The queue has 1881 threads.
Active threads: 100. The queue has 1882 threads.
Active threads: 100. The queue has 1883 threads.
文档说 threadPoolExecutor.getActiveCount()
方法
returns the approximate number of threads that are actively executing
tasks
但是为什么这个近似值的最大阈值总是maximumPoolSize
/2?应该是这样吗?
P.S。我无法重现这种情况:在这种情况下,在我的 PC 上我总是有 200 个活动线程。但是上面的日志不是来自我的电脑。它可以取决于 processors/virtual 核心的数量吗?
我还在The Grey Blog中找到了一段有趣的代码:
int cpus = Runtime.getRuntime().availableProcessors();
int maxThreads = cpus * scaleFactor;
maxThreads = (maxThreads > 0 ? maxThreads : 1);
但最终我很困惑,因为Runtime.getRuntime().availableProcessors()
的值在我的电脑上是8。
您确定变量 maximumPoolSize
设置为 200
。它在我这边工作正常。
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class SO35570728 {
private class Task implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " started");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " finished");
}
}
public static void main(String[] args) {
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(200, 200, 50000L, TimeUnit.MILLISECONDS, queue);
for(int i= 0 ; i < 100000 ; i++){
System.out.println("Active threads: " + threadPoolExecutor.getActiveCount() + ". The queue has " + queue.size() + " threads.");
threadPoolExecutor.submit(new SO35570728().new Task());
}
}
}
输出
Active threads: 0. The queue has 0 threads.
Active threads: 1. The queue has 0 threads.
Active threads: 2. The queue has 0 threads.
Active threads: 3. The queue has 0 threads.
...
pool-1-thread-1 started
pool-1-thread-2 started
pool-1-thread-3 started
...
Active threads: 200. The queue has 99793 threads.
Active threads: 200. The queue has 99794 threads.
Active threads: 200. The queue has 99795 threads.
Active threads: 200. The queue has 99796 threads.
Active threads: 200. The queue has 99797 threads.
Active threads: 200. The queue has 99798 threads.
Active threads: 200. The queue has 99799 threads.
我们有一个任务队列,它的初始化看起来像:
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(maximumPoolSize, maximumPoolSize, 50000L, TimeUnit.MILLISECONDS, queue);
maximumPoolSize
的值为200。队列工作时得到大量线程(超过一千),但threadPoolExecutor.getActiveCount()
返回的值总是小于或等于100 . 例如,值 threadPoolExecutor.getActiveCount()
和 queue.size()
记录如下:
logger.debug("Active threads: " + threadPoolExecutor.getActiveCount() + ". The queue has " + queue.size() + " threads.");
结果我们得到以下日志:
Active threads: 1. The queue has 0 threads.
Active threads: 2. The queue has 0 threads.
Active threads: 3. The queue has 0 threads.
Active threads: 4. The queue has 0 threads.
Active threads: 5. The queue has 0 threads.
...
Active threads: 86. The queue has 0 threads.
Active threads: 87. The queue has 1 threads.
Active threads: 88. The queue has 1 threads.
Active threads: 89. The queue has 1 threads.
Active threads: 90. The queue has 1 threads.
...
Active threads: 99. The queue has 1 threads.
Active threads: 100. The queue has 1 threads.
Active threads: 100. The queue has 2 threads.
Active threads: 100. The queue has 3 threads.
Active threads: 100. The queue has 4 threads.
...
Active threads: 100. The queue has 1874 threads.
Active threads: 100. The queue has 1875 threads.
Active threads: 100. The queue has 1876 threads.
Active threads: 100. The queue has 1877 threads.
Active threads: 100. The queue has 1878 threads.
Active threads: 100. The queue has 1879 threads.
Active threads: 100. The queue has 1880 threads.
Active threads: 100. The queue has 1881 threads.
Active threads: 100. The queue has 1882 threads.
Active threads: 100. The queue has 1883 threads.
文档说 threadPoolExecutor.getActiveCount()
方法
returns the approximate number of threads that are actively executing tasks
但是为什么这个近似值的最大阈值总是maximumPoolSize
/2?应该是这样吗?
P.S。我无法重现这种情况:在这种情况下,在我的 PC 上我总是有 200 个活动线程。但是上面的日志不是来自我的电脑。它可以取决于 processors/virtual 核心的数量吗?
我还在The Grey Blog中找到了一段有趣的代码:
int cpus = Runtime.getRuntime().availableProcessors();
int maxThreads = cpus * scaleFactor;
maxThreads = (maxThreads > 0 ? maxThreads : 1);
但最终我很困惑,因为Runtime.getRuntime().availableProcessors()
的值在我的电脑上是8。
您确定变量 maximumPoolSize
设置为 200
。它在我这边工作正常。
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class SO35570728 {
private class Task implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " started");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " finished");
}
}
public static void main(String[] args) {
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(200, 200, 50000L, TimeUnit.MILLISECONDS, queue);
for(int i= 0 ; i < 100000 ; i++){
System.out.println("Active threads: " + threadPoolExecutor.getActiveCount() + ". The queue has " + queue.size() + " threads.");
threadPoolExecutor.submit(new SO35570728().new Task());
}
}
}
输出
Active threads: 0. The queue has 0 threads.
Active threads: 1. The queue has 0 threads.
Active threads: 2. The queue has 0 threads.
Active threads: 3. The queue has 0 threads.
...
pool-1-thread-1 started
pool-1-thread-2 started
pool-1-thread-3 started
...
Active threads: 200. The queue has 99793 threads.
Active threads: 200. The queue has 99794 threads.
Active threads: 200. The queue has 99795 threads.
Active threads: 200. The queue has 99796 threads.
Active threads: 200. The queue has 99797 threads.
Active threads: 200. The queue has 99798 threads.
Active threads: 200. The queue has 99799 threads.