java - newFixedThreadPool.setCorePoolSize() 不使用线程,创建新的线程,这可能是开销

标签 java multithreading threadpool threadpoolexecutor

newFixedThreadPool.setCorePoolSize() 不使用线程,创建新线程。

解释: 我创建了一个大小为 2 的 newFixedThreadPool,如果该池的两个线程都忙,我将使用 setCorePoolSize() 向该池添加另外两个线程。在此过程中,它似乎没有重用线程,或者可能终止一些线程并创建新线程,我将用代码解释。

代码:(另请参阅输出了解)

public class IncreasePoolSize
{
    static ExecutorService service = null;
    public static void main(String[] args) throws JMSException, InterruptedException
    {
        int NoOfth = 2;
        int noOfTimesToInc = 0;
        System.out.println("Start");
        service = Executors.newFixedThreadPool(NoOfth);
        for (;;)
        {
            if ( ((ThreadPoolExecutor)service).getActiveCount() >= NoOfth )
            {
                if (noOfTimesToInc < 1)
                {
                    System.out.println("Increased Threads-" + (noOfTimesToInc + 1) + " time(s)");
                    NoOfth += 2;
                    System.out.println("NoOfTh-" + NoOfth);
                    ((ThreadPoolExecutor)service).setCorePoolSize(NoOfth);
                    System.out.println("Total no of theads after increasing-" + ((ThreadPoolExecutor)service).getCorePoolSize());
                    noOfTimesToInc++;
                }

            }
            else if ( ((ThreadPoolExecutor)service).getActiveCount() <= NoOfth)
            {
                service.execute(new ConcreteThread());
            }
        }
    }

}

class ConcreteThread implements Runnable
{
    public void run() 
    {
        try
        {
             System.out.println("Thread No-" + Thread.currentThread().getId());
             Thread.sleep(5000);
             System.out.println("Thread No-" + Thread.currentThread().getId() + " finished");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

在输出中可以看到,一旦线程 11 和 12 开始工作,我将数字增加 2,因此线程 13 和 14 开始工作,但在那之后,我总是创建新线程而不是使用线程 11 和 12 和重用线程 13 和 14。

输出:(在 Debug模式下运行)

Start
Thread No-11
Thread No-12
Increased Threads-1 time(s)
NoOfTh-4
Total no of theads after increasing-4
Thread No-13
Thread No-14
Thread No-11 finished
Thread No-12 finished
Thread No-13 finished
Thread No-14 finished
Thread No-15
Thread No-16
Thread No-13
Thread No-14
Thread No-15 finished
Thread No-16 finished
Thread No-13 finished
Thread No-14 finished
Thread No-17
Thread No-18
Thread No-13
Thread No-14
Thread No-17 finished
Thread No-18 finished
Thread No-13 finished
Thread No-14 finished
Thread No-19
Thread No-20
Thread No-13
Thread No-14
Thread No-19 finished
Thread No-20 finished
Thread No-13 finished
Thread No-14 finished
Thread No-21
Thread No-22
Thread No-13
Thread No-14
Thread No-21 finished
Thread No-22 finished
Thread No-13 finished
Thread No-14 finished
Thread No-23
Thread No-24
Thread No-13
Thread No-14

最佳答案

代码的一个问题是您设置了核心池大小而不是最大池大小。 newFixedThreadPool 使用相同数量的核心和最大池大小,您在某种程度上违反了该契约(Contract)。

如果你添加:

service.setMaximumPoolSize(NoOfth);

设置核心池大小后,将按预期重用相同的 4 个线程。

注意:这实际上是a reported bug

如果 corePoolSize > maximumPoolSize,ThreadPoolExecutor 和 setMaximumPoolSize 的构造函数会抛出 IllegalArgumentException,但 setCorePoolSize 不会。

关于java - newFixedThreadPool.setCorePoolSize() 不使用线程,创建新的线程,这可能是开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17044045/

相关文章:

java - 哪个 api/sdk 在 Android 平台上从帐户/页面获取图像简单且有用?

java - 反射从方法参数注释获取值

c - 将大量线程固定到单个 CPU 会导致所有内核的利用率激增

java - 同步数据读/写到/从主存储器

python - 在 Python 中停止线程池中的进程

c# - ios monotouch 的 UIProgressView 跟踪下载状态

java - 使用 JTATransactionManager 处理事务?

java - 非 DST 时区的 Joda 时间转换不正确

c++ - QT线程中的Lua脚本

c# 多线程应用程序中的 TCP 耗尽