23

I've just started looking at Java's Executors class and the newCachedThreadPool( ) method. According to the API, the resulting thread pool reuses existing Thread objects for new tasks.

I'm a bit puzzled how this is implemented because I couldn't find any method in the Thread API that lets you set the behaviour of an existing Thread object.

For example, you can create a new Thread from a Runnable object, which makes the Thread call the Runnable's run( ) method. However, there is no setter method in the Thread API that takes a Runnable as an argument.

I'd appreciate any pointers.

Marc van Dongen
  • 534
  • 4
  • 15
  • The answer IOW: a `Thread` performs almost the same task (or should I say subset of tasks) as the combination of `Runnable` and `ExecutorService` with the exception that the latter combo gives you more features to take advantage of. So much so that you should *really* be considering why you are using a `Thread` alone if doing so. – BAR Sep 07 '15 at 21:39

6 Answers6

28

Basically imagine each thread from the pool doing this:

public void run() {
    while(true) {
        if(tasks available) {
           Runnable task = taskqueue.dequeue();
           task.run();
        } else {
           // wait or whatever
        }
    }
}
Tudor
  • 61,523
  • 12
  • 102
  • 142
5

The threadpool has threads that look for runnable jobs. Instead of starting a new thread from the Runnable the thread will just call the function run(). So a thread in a ThreadPool isn't created with the Runnable you provide,but with one that just checks if any tasks are ready to be executed and calls them directly.

So it would look something like this:

while(needsToKeepRunning()){
    if(hasMoreTasks()){
        getFirstTask().run();.
    }
    else
    {
        waitForOtherTasks();
    }
}

Of course this is overly simplified the real implementation with the waiting is much more elegant. A great source of information on how this really works can be found in Concurrency in Practice

Thirler
  • 20,239
  • 14
  • 63
  • 92
4

Threads are created only once in the Thread Pool API (except in the cases when due to some exception the thread exits abruptly)

The Worker threads poll the Queue to see if there is a task and use it. So the threads never exit.

It is just an abstraction that Threads are reused (Abstraction for they never actually stop). Obviously they stop after idle timeout and shutdown request.

Runnable -----> Thread Pools (Some worker thread consumes that Runnable and others wait for some more Runnables)

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
2

Executors does everything for you in the background. And yes it uses the existing thread API only.

Below link has sample implementation of Thread pool implemented using Thread class and Collection API: http://www.ibm.com/developerworks/library/j-jtp0730/index.html

rai.skumar
  • 10,309
  • 6
  • 39
  • 55
  • For some reason my first comment wasn't posted. Thanks for clarifying. When I posted the question I wrongly assumed the threads had no knowledge of the thread pool's internals. – Marc van Dongen Dec 04 '12 at 09:41
2

Well the thread only have to call Runnable.run() on the runnables which are assigned to him...

UmNyobe
  • 22,539
  • 9
  • 61
  • 90
2

A simplified explanation is that when you pass a Runnable to the ExecutorService the Runnable is put into a queue. The ThreadPool worker threads reads from this queue and invokes the queued Runnables run() method.

Fredrik LS
  • 1,480
  • 9
  • 15