I have always read that creating threads is expensive.
I also know that you cannot rerun a thread.
I see in the doc of Executors
class:
Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available.
Mind the word 'reuse'.
How do thread pools 'reuse' threads?
There is no "reuse" in this case. So it is true that you cannot call start() on a Java Thread twice but you can pass as many Runnable as you want to an executor and each Runnable 's run() method shall be called once.
Thread Pool: Reusing Existing Thread To Save MemoryThread Pool Pattern stands for reusing existing threads and running all new instructions without allocation of new threads. The thread pool controls the number of running threads and is widely used in production. This pattern has implementations in Java: Executors.
Java Thread pool represents a group of worker threads that are waiting for the job and reused many times. In the case of a thread pool, a group of fixed-size threads is created. A thread from the thread pool is pulled out and assigned a job by the service provider.
I think I understood what is confuzzabling you so here's my longer answer: the terminology is a tiny bit misleading (obviously, or you wouldn't ask that question specifically putting the emphasis on 'reuse'):
How do thread pools 'reuse' threads?
What is happening is that a single thread can be used to process several tasks (typically passed as Runnable
, but this depend on your 'executor' framework: the default executors accepts Runnable
, but you could write your own "executor" / thread-pool accepting something more complex than a Runnable
[like, say, a CancellableRunnable
]).
Now in the default ExecutorService
implementation if a thread is somehow terminated while still in use, it is automatically replaced with a new thread, but this is not the 'reuse' they're talking about. There is no "reuse" in this case.
So it is true that you cannot call start()
on a Java Thread twice but you can pass as many Runnable
as you want to an executor and each Runnable
's run()
method shall be called once.
You can pass 30 Runnable
to 5 Java Thread
and each worker thread may be calling, for example, run()
6 times (practically there's not guarantee that you'll be executing exactly 6 Runnable
per Thread
but that is a detail).
In this example start()
would have been called 6 times. Each one these 6 start()
will call exactly once the run()
method of each Thread
:
From Thread.start()
Javadoc:
* Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread.
BUT then inside each Thread's run()
method Runnable
shall be dequeued and the run()
method of each Runnable
is going to be called. So each thread can process several Runnable
. That's what they refer to by "thread reuse".
One way to do your own thread pool is to use a blocking queue on to which you enqueue runnables and have each of your thread, once it's done processing the run()
method of a Runnable
, dequeue the next Runnable
(or block) and run its run()
method, then rinse and repeat.
I guess part of the confusion (and it is a bit confusing) comes from the fact that a Thread
takes a Runnable
and upon calling start()
the Runnable 's run()
method is called while the default thread pools also take Runnable
.
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