Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when does executor really create new thread

I'm confused about when new threads are created as for executor. My understanding is: as for cachedthreadpool, new threads are created according to the submission of tasks. As for fixedthreadpool and singlethread, thread is created in advance regardless of the submission of tasks. Is my understanding wrong?

ExecutorService exec = Executors.newCachedThreadPool(); 
exec.execute(new LiftOff());

ExecutorService exec = Executors.newFixedThreadPool(3); // Are the three threads created 
                                                        // after this line executes?
exec.execute(new LiftOff());

ExecutorService exec = Executors.newSingleThreadExecutor(); // Is the single thread created 
                                                            // after this line executes?
exec.execute(new LiftOff());
like image 844
user7328234 Avatar asked Apr 23 '17 09:04

user7328234


People also ask

Does newSingleThreadExecutor create a new thread?

newSingleThreadExecutor. Creates an Executor that uses a single worker thread operating off an unbounded queue, and uses the provided ThreadFactory to create a new thread when needed.

Does Executor service reuse threads?

The old available threads are reused for the new tasks. Method: Executors. newCachedThreadPool() Fixed Thread Pool: A thread pool with a fixed number of threads.

How does thread pool Executor works?

ThreadPoolExecutor is an ExecutorService to execute each submitted task using one of possibly several pooled threads, normally configured using Executors factory methods. It also provides various utility methods to check current threads statistics and control them.

What happens to a thread after execution?

Thread is dead itself after its run method returns. It might still be in the heap, but it will not have its own stack anymore, and not do anything.


1 Answers

Short answer is that in all cases you mentioned, threads are created only when you start executing the tasks, i.e. no threads will be created after this ExecutorService exec = Executors.newFixedThreadPool(3); line is executed, and first thread will be created only after this exec.execute(new LiftOff()); line is executed.


To better and fully understand this, as @Oliver has advised you need to walk through Java source code and also read about ThreadPoolExecutor, especially what is core pool size, max pool size etc. If you want to quickly understand this in layman's word then read this good answer.

Now, below are few good points to understand before I take you to some sample code:

  • Java's utility class Executors will create and return objects of ExecutorService (please note that ExecutorService is an interface).
  • Now in case of newCachedThreadPool(), newFixedThreadPool(int nThreads) you will get an object of ThreadPoolExecutor (please note that ThreadPoolExecutor implements ExecutorService interface).
  • As you can see in the source code, when you do Executors.newFixedThreadPool(3);, you only get an object of ThreadPoolExecutor with all instance variables like core pool size, max pool size etc. set, and in your case it will be set to 3.
  • At this point no threads are created, and actual thread creation only happens when you start executing tasks using execute, submit or invokeAll.
  • As you can see in source code, when you do first execute it will create only 1 new thread if current pool size is less than core pool size, so this is where your thread start getting created.

Please see below sample code which will help you understand and prove that threads are created only when you start executing the tasks. To explain you, main trick I did is I used the object reference variable of ThreadPoolExecutor so that I can call method like getPoolSize() (please note that getPoolSize() tells about how many threads are currently present in the pool), because when you use object reference variable of ExecutorService then you cannot call these methods (I am sure I need not to tell "why").

When you will run this example you will note that:

  • There were no threads created after ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
  • After first executeRunnable(poolExecutor); you got one thread in the pool.
  • Since you have used core pool size as 3, so after creating 3 threads no more threads were created. (do read about core, max pool size and "queue" size)

package com.learn.stackoverflow.multithreading;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 
 * @author himanshu.agrawal
 *
 */
public class ExecutorServiceNumberOfThreads {
    public static void main(String[] args) {
        System.out.println("### Testing Executors.newFixedThreadPool()");
        testNewFixedThreadPool();
    }

    private static void testNewFixedThreadPool() {
        ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
        System.out.println("Pool when no execute() : " + poolExecutor.getPoolSize());
        executeRunnable(poolExecutor);
        System.out.println("Pool after 1st execute() : " + poolExecutor.getPoolSize());
        executeRunnable(poolExecutor);
        System.out.println("Pool after 2nd execute() : " + poolExecutor.getPoolSize());
        executeRunnable(poolExecutor);
        System.out.println("Pool after 3rd execute() : " + poolExecutor.getPoolSize());
        executeRunnable(poolExecutor);
        System.out.println("Pool after 4th execute() : " + poolExecutor.getPoolSize());
        executeRunnable(poolExecutor);
        System.out.println("Pool after 5th execute() : " + poolExecutor.getPoolSize());
    }

    private static void executeRunnable(ThreadPoolExecutor poolExecutor) {
        poolExecutor.execute(new Runnable() {

            @Override
            public void run() {
                System.out.println("Running: " + Thread.currentThread().getId() + " | " + new Date());
            }
        });
    }

}

Output:

### Testing Executors.newFixedThreadPool()
Pool when no execute() : 0
Pool after 1st execute() : 1
Pool after 2nd execute() : 2
Pool after 3rd execute() : 3
Pool after 4th execute() : 3
Pool after 5th execute() : 3
Running: 10 | Sun Apr 23 19:50:32 IST 2017
Running: 8 | Sun Apr 23 19:50:32 IST 2017
Running: 10 | Sun Apr 23 19:50:32 IST 2017
Running: 9 | Sun Apr 23 19:50:32 IST 2017
Running: 8 | Sun Apr 23 19:50:32 IST 2017
like image 103
hagrawal Avatar answered Oct 31 '22 08:10

hagrawal