How Java's ThreadPoolExecutor uses custom ThreadFactory?
-
26-05-2021 - |
Question
The ThreadPoolExecutor class allows to give a custom ThreadFactory to create new threads. However, I do not understand how these threads are used within sun's implementation of ThreadPoolExecutor.
This implementation creates new thread as follows:
private Thread addThread(Runnable firstTask) {
Worker w = new Worker(firstTask);
Thread t = threadFactory.newThread(w);
if (t != null) {
w.thread = t;
...
} ...
But in Worker's implementation, I do not see how field "thread" is used as the runner.
Furthermore, I do not understand how one can provide Thread with custom "run" method that are reused (where reused - as in ThreadPoolExecutor - mean "they run multiple Runnable"). How can ThreadPoolExecutor reuse such threads to run multiple Runnable (given that the "target" Runnable in class Thread is set at construction time and there's no setter). ThreadPoolExecutor's documentation is as follows:
By supplying a different ThreadFactory, you can alter the thread's name, thread group, priority, daemon status, etc.
Does this mean that the "run" method of threads created by a custom ThreadFactory is not used ? That's the only way I would understand the "custom threads creation + thread 'reuse'" mechanism.
Solution
But in Worker's implementation, I do not see how field "thread" is used as the runner.
As newThread() documentation states, the newly created thread must run the Runnuble supplied as the argument to threadFactory.newThread(Runnuble). This is the way new thread is used as the runner.
Furthermore, I do not understand how one can provide Thread with custom "run" method that are reused
Again, thread's run method must run the supplied Runnable.run() once. The thread poll supplies Worker which runs tasks in a loop. Example of correct user-implemented thread:
public class ThreadTL extends Thread {
public ThreadTL(Runnable r) {
super(r);
setName(getName()+" DF "+executor.getClass().getSimpleName());
}
@Override
public void run() {
super.run();
}
}
OTHER TIPS
One Runnable can call another. The Runnable you get passed is one which gets Runnables from the thread pools queue and runs those.