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