Reusing java thread through the executor

advertisements

I am confused on the following:
To use threads in a Java program, the simplest way is to extend Thread class and implement the runnable interface (or simply implement runnable).
To start the thread's execution. we must call the Thread's method start(), which in turn calls method run() of the thread. And so the thread starts.
The method start() (unless I am wrong) must be called exactly and only once for each thread. As a result, thread instances can not be reused unless somehow the run method itself runs in some-short of infinite loop that facilitates a custom implementation of the thread's reusage.
Now the javadoc link text says

Calls to execute will reuse previously constructed threads if available

I do not understand how this is implemented. I provide in the execute method of the executor method my custom thread e.g.

  ExecutorService myCachedPool = Executors.newCachedThreadPool();
  myCachedPool.execute(new Runnable(){public void run(){
     //do something time consuming

  }});

How can this custom thread I delegeate to the executor framework be reused?
Is Executor is allowed to call method start() more than 1 time, while we can not in our programs? Am I misunderstanding something?

Thank you.


Note that it's not Executor that calls start() - it's ExecutorService. And no, it's not calling start() twice. It doesn't start the task that you give it directly using Thread.start()... instead, it starts a thread which knows about that thread pool's queue of work. The thread will basically wait until there's some work to do, then pick it up and execute it, before going back to waiting. So although the thread performs several tasks, Thread.start() is only called once.

EDIT: Judging by the comments, you're a bit confused about the difference between a Runnable (which is a task to be executed) and a Thread (which is what executes tasks).

The same thread can execute multiple tasks. For a very simple example not using a thread pool, consider this:

public class MultiRunnable implements Runnable
{
    private final List<Runnable> runnables;

    public MultiRunnable(List<Runnable> runnables)
    {
        this.runnables = runnables;
    }

    public void run()
    {
        for (Runnable runnable : runnables)
        {
             runnable.run();
        }
    }
}

(Ignore the potential thread safety issues of using a List<T> from multiple threads.)

You could create a whole bunch of Runnable tasks capable of doing different things, then create a single MultiRunnable to run them in turn. Pass that instance of MultiRunnable into the Thread constructor, and then when you start the thread, it will execute each of the original runnable tasks. Does that help?