Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

newFixedThreadPool.setCorePoolSize() doesn't make use of the threads, creates new theads which may be overhead

newFixedThreadPool.setCorePoolSize() doesn't make use of the threads, creates new theads.

Explanation: I make a newFixedThreadPool for size 2 and if both the threads of this pool are busy I add two more threads to this pool using setCorePoolSize(). In this process it doesn't seem to reuse the threads or may be terminating some threads and creating new which I will explain with code.

Code: (Please also see the Output for understanding)

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();
        }
    }
}

It is seen in the output once thread no 11 and 12 start working, I increase the number by two and so thread 13 and 14 start working, but after that, i always creates new thread instead of using thread 11 and 12 and reuses thread 13 and 14.

Output:(have run it in debug mode)

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

like image 384
user578219 Avatar asked Jun 11 '13 12:06

user578219


2 Answers

One issue with your code is that you set the core pool size but not the maximum pool size. A newFixedThreadPool uses the same number of core and maximum pool size and you somewhat break that contract.

If you add:

service.setMaximumPoolSize(NoOfth);

after setting the core pool size, the same 4 threads will be reused as you expect.

Note: this is actually a reported bug

The constructor of ThreadPoolExecutor and setMaximumPoolSize throw an IllegalArgumentException if corePoolSize > maximumPoolSize, but setCorePoolSize does not.

like image 131
assylias Avatar answered Oct 11 '22 06:10

assylias


According to the javadoc of Executors.newFixedThreadPool:

Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks

So, it is not necessarily creating new threads, it is just using different threads from a shared unbounded queue.

What the fixed thread pool is giving you is not that it will always use the exact same thread objects, but that the number of active threads working tasks in that executor will NEVER exceed the limit of the pool.

like image 43
John B Avatar answered Oct 11 '22 06:10

John B