Reputation: 45722
I read that ThreadPoolExecutor
has pool of threads and this pool is destined to reduce cost of creation new threads (at least I understood phrase below in such way):
When you send a task to the executor, it tries to use a pooled thread for the execution of this task, to avoid continious spawning of threads. [Java 7 Concurrency Cookbook]
BUT, as I know we have got no way to restart thread in Java.
Question: How does ThreadPoolExecutor avoid creation of new threads?
Upvotes: 11
Views: 3979
Reputation: 61198
It's very simple - in essence the Thread
s sleep, waiting to be woken by a task - they run that task and then sleep again.
public static void main(final String[] args) throws Exception {
final BlockingQueue<Runnable> blockingQueue = new LinkedBlockingDeque<>();
final Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
blockingQueue.take().run();
} catch (InterruptedException ex) {
return;
}
}
}
});
t.start();
blockingQueue.add(new Runnable() {
@Override
public void run() {
System.out.println("Task 1");
}
});
blockingQueue.add(new Runnable() {
@Override
public void run() {
System.out.println("Task 2");
}
});
}
The BlockingQueue
will block a Thread
while it is empty. When I add an item, and Thread
(s) currently blocked are awoken and one will take the task (LinkedBlockingDeque
is thread safe). When the Thread
is done with the task it goes back to sleep.
The JavaDoc for ThreadPoolExecutor
describes the logic in detail. All of the constructors for ThreadPoolExecutor
take a BlockingQueue<Runnable>
- this should give you a hint as so how the logic works.
NB: This is not the same as busy waiting. A BlockingQueue
uses wait
and notify
to suspend and wake Thread
s, this means that the Thread
s in the pool are not doing any work when they are not processing tasks. A busy wait based approach would not work because the Thread
s would block up all the CPU cores with their polling not allowing the program to proceed (or at least severely impairing it).
Upvotes: 15