Search code examples
javamultithreadingthreadpooljava.util.concurrentthreadpoolexecutor

Threadpool re-use of threads


I know this topic has been asked a lot, but im not sure about one detail. Now threadpool doesnt let a thread die after completing a task, and reuses it later on as needed (as it is said here, here, etc) But let say my runnable has variables in the constuctor -

MyRunnable(int a){
  this.a = a; 
}

then, when we try to run the Runnable with a Executors.newFixedThreadPool (or something similar), we say

executor.execute(new MyRunnable(a)); // executor being Executors.newFixedThreadPool

now if variable 'a' is different in every execute, can Threadpool really reuse it later? I cant really understand how that would work, but i never seen 'Threadpool reuses threads except...', hence the confusion.


Solution

  • No, neither the Runnable you submit, nor the variables related to it, will be reused.

    I think you mis-understood Thread and Runnable, they are different things. A Runnable is just normal object, execept its run method will be executed when you create a new thread with it. You can check this question.

    The re-use of thread does not mean the re-use of Runnable, it means the thread keeps executing different Runnables.


    When you create a Thread with a Runnable, and start this thread like this:

    new Thread(new Runnable()).start()
    

    the run() method of this Runnale will be executed, and after the run() exiting, this Thread will terminate too.

    But, the Runnbale you submit to the ThreadPoolExecutor is not the one in code above to construct the thread.


    Briefly, threads in ThreadPoolExecutor are created like this:

    Runnable worker = new Runnable() {
    
        @Override
        public void run() {
            Runnable firstTask = getFirstTask();  // the first runnable 
            firstTask.run();
    
            Runnable queuedTask;
            while ( (queuedTask = getTaskFromQueue()) != null) {  // This could get blocked 
                queuedTask.run();
            }
        }
    };
    new Thread(worker).start();
    

    Note, the Runnable used to initate the thread is not the one you submitted to the pool.


    When you submit new Runnable, the thread pool will check if it need to create new thread(based on the argument like corePoolSize).

    • If it is necessary, then it create a new Worker with this Runnable as FirstTask, and create a new thread with this Worker and start it.
    • If not, then it put the Runnbale in a queue. When there are free threads, they will check this queue and take tasks from it.