Java 为什么总是threadPoolExecutor.getActiveCount()<;=最大内存大小/2?

Java 为什么总是threadPoolExecutor.getActiveCount()<;=最大内存大小/2?,java,threadpoolexecutor,Java,Threadpoolexecutor,我们有一个任务队列,其初始化如下所示: LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(maximumPoolSize, maximumPoolSize, 50000L, TimeUnit.MILLISECONDS, queue); 因此,我们得

我们有一个任务队列,其初始化如下所示:

LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(maximumPoolSize, maximumPoolSize, 50000L, TimeUnit.MILLISECONDS, queue);
因此,我们得到以下日志:

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()
方法

返回活动执行的线程的大致数目 任务

但是为什么这个近似值的最大阈值总是
maximumPoolSize
/2?应该是这样吗

另外,我无法重现这种情况:在我的电脑上,这种情况下我总是有200个活动线程。但是上面的日志不是我电脑上的。它能否取决于处理器/虚拟核的数量

我还发现了一段有趣的代码:


但最终我还是很困惑,因为在我的电脑上,
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());
        }
    }
}

您确定变量
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());
        }
    }
}

注意:除非您有这么多逻辑CPU,否则您可能会发现拥有更多线程的速度较慢,尽管看起来确实像@VickyThakor建议的那样将最大值设置为100。@PeterLawrey,我编辑了我的帖子,建议您打印
threadPoolExecutor.getPoolSize()
最大值不取决于您拥有的内核数量,只有在这一点上,拥有更多不是一个好主意。将
threadPoolExecutor.getMaximumPoolSize()
添加到日志中-确保
maximumPoolSize
实际上是200。注意:除非您拥有这么多逻辑CPU,否则您可能会发现拥有更多线程的速度较慢,尽管看起来你确实像@VickyThakor建议的那样将最大值设置为100。@PeterLawrey,我编辑了我的帖子,建议你打印
threadPoolExecutor.getPoolSize()
最大值不取决于你拥有的内核数量,只取决于拥有更多内核不是一个好主意的点。添加
threadPoolExecutor.getMaximumPoolSize()
到日志-确保
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.