How Threadpool re-use Threads and how it works

JavaMultithreadingConcurrencyThreadpool

Java Problem Overview


My multithreading concepts are weak and trying to learn.

In Java what I know is, we can't call a thread more than once:

Thread t = new Thread; //Some Runnable
t.start();

t.start(); //Illegal and throw Exception at runtime.

As far as I know, it throws exception when you call t.start() again because the associated stack for the thread is destroyed once it goes out of run() method and you are trying to initialize things again.

In that case, what I know about thread pool is, it gives better performance & saves time because there is no need to create new thread (I read in this).

If there is no need to create new thread in thread pool scenario, then how it works with same thread which just finished its run method, will that thread can be used again?

I read this, and it says that "Most of the executor implementations in java.util.concurrent use thread pools, which consist of worker threads. This kind of thread exists separately from the Runnable and Callable tasks it executes and is often used to execute multiple tasks."

So what is Worker thread here, is it something different then normal Java threads?

With this link, I got something but still confused on what kind of stuff can be eliminated when we use thread pool and why it gives better performance than using normal java threads.

So can we say like this,

Thread has three parts,

  1. Creation (Telling OS that it is new thread, create stack for it.)
  2. Execute Runnable with run() method.
  3. Destroying threads.

So, considering above 3 steps, With thread pool step 1 and step 3 can be eliminated after fixed number of thread creation. Only step 2 for each task will be executed that is why threadpool is faster? Can we say like this? Am I correct?

Java Solutions


Solution 1 - Java

> If there is no need to create new Thread in ThreadPool scenario, then how it works with same thread which just finished its run method, will that Thread can be used again?

Simple - the original thread never actually completes. It just waits for another task to execute. In pseudo-code:

// No, this isn't even slightly accurate! General impression only :)
while (!pool.isShutdown()) {
    Runnable task = pool.waitForTaskOnQueue();
    task.run();
}

(Obviously when a thread pool is shut down, it would need to stop waiting threads from waiting for another task, too - but hopefully you get the general idea.)

Solution 2 - Java

The process workes in two parts:

Submission of task: Thread pools are tightly coupled with a blocking Queue. When we say executor.execute(runnable). The runnable/callable is enqued in the queue.

Execution of tasks: Now the tasks need to be picked up from the queue. Lets say whenever a task is submitted in the queue, it must be picked up and executed.

So there are threads which will be running infinite loop and watching the queue for tasks. As soon as the tasks are available one thread will pick it and execute.

Solution 3 - Java

In Thread Pool Instead of creating new threads when new tasks arrive, a thread pool keeps a number of idle threads that are ready for executing tasks as needed. After a thread completes execution of a task, it does not die. Instead it remains idle in the pool waiting to be chosen for executing new tasks.

You can limit a definite number of concurrent threads in the pool, which is useful to prevent overload. If all threads are busily executing tasks, new tasks are placed in a queue, waiting for a thread becomes available

Solution 4 - Java

> So, considering above 3 steps, With Threadpool step 1 and Step 3 can > be eliminated after fixed number of Thread Creation. only Step 2 for > each task will be executed that is why Threadpool is faster? can we > say like this? am I correct?

Yes you are correct. Thread creation and destruction is one of the costly task. As in a thread pool threads are already created so the overhead of thread creation is not there. But if you have much more higher threads than it should have, it will be pretty bad for your application. It may go OutofMemorry or may be into some other issues. So to fix a thread pool size use the below formula:

no of threads = 2 * no_of_cores * no_of_disks * percentage CPU utilization you need * (1 + (W/ C))

(W/C) is the fraction stating Wait time to Compute time.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJayeshView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavaSonuView Answer on Stackoverflow
Solution 3 - JavaVinayak BansalView Answer on Stackoverflow
Solution 4 - JavaTryingView Answer on Stackoverflow