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());
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.
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.
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.
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.
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:
Executors
will create and return objects of ExecutorService
(please note that ExecutorService
is an interface). newCachedThreadPool()
, newFixedThreadPool(int nThreads)
you will get an object of ThreadPoolExecutor
(please note that ThreadPoolExecutor
implements ExecutorService
interface).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.execute
, submit
or invokeAll
.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:
ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
executeRunnable(poolExecutor);
you got one thread in the pool.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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With