0

I faced a problem about ThreadPoolExecutor.

After writing some code, I found the submit() method will eat the RuntimeException thrown by the program, but the execute() method will re-throw the RuntimeException`. I want to know the reason for this.

I recently read the source code of ThreadPoolExecutor and know the principle of a thread pool. Now I understand how execute() method executes, but I couldn't understand how submit() method executes. I only know that the submit() method will wrap the Runnable or Callable in a FutureTask and call the execute() method:

public Future submit(Runnable runnable)
{
    if(runnable == null)
    {
        throw new NullPointerException();
    } else
    {
        RunnableFuture runnablefuture = newTaskFor(runnable, null);
        execute(runnablefuture);
        return runnablefuture;
    }
}

So, my problem is: how does ThreadPoolExecutor execute FutureTask and why is the RuntimeException eaten?

  • 3
    a good explanation is here http://stackoverflow.com/questions/3929342/choose-between-executorservices-submit-and-executorservices-execute – Tala Jun 23 '13 at 15:47
  • I know the submit() method will bind the exception to Future,but after reading the source code of ThreadPoolExecutor,I didn't find the place where it did? So I want to know how the submit() method bind the exception to Future? – binnchx chen Jun 24 '13 at 02:56
  • answered with explanation – Tala Jun 24 '13 at 07:49

1 Answers1

0

If you look into newTaskFor method you'll see that RunnableFuture is in fact instance of java.util.concurrent.FutureTask. You should see the run method in this FutureTask class.

public void run() {
    sync.innerRun();
}

and here is the innerRun method:

    void innerRun() {
        if (!compareAndSetState(READY, RUNNING))
            return;

        runner = Thread.currentThread();
        if (getState() == RUNNING) { // recheck after setting thread
            V result;
            try {
                result = callable.call();
            } catch (Throwable ex) {
                setException(ex);
                return;
            }
            set(result);
        } else {
            releaseShared(0); // cancel
        }
    }

the exception is caught and set to task. It will be thrown wrapped into ExecutionException when you call get method of FutureTask

 public V get() throws InterruptedException, ExecutionException {
    return sync.innerGet();
}
Tala
  • 8,888
  • 5
  • 34
  • 38
  • thank you. I find the answer, in the method runTask(Runnable runnable) of ThreadPoolExecutor, runnable.run() will be called, so the run method of the runnale or the fufureTask will be called. – binnchx chen Jun 24 '13 at 10:43
  • I explained to you the difference between submit and execute. I thought that that's what you asked for and how exception is eaten – Tala Jun 24 '13 at 10:47