John Hinnegan
John Hinnegan

Reputation: 5962

Catching Exceptions from (ExecutorService) CachedThreadPool

We are using a CachedThreadPool created via the ExecutorService#newCachedThreadPool. (Java 1.6). We are getting errors elsewhere in our code: "unable to create new native thread" which we've diagnosed as an out of memory problem. When this problem is happening, the block of code where we call submit (we use submit, not execute) slows down. We suspect that the ThreadPool is having the same issue "unable to create new native thread" when it is trying to create new threads to process the tasks, but we can't be sure.

Is there any way to catch exceptions from inside the ExecutorService? To be 100% clear, I'm not talking about the tasks given to the ExecutorService, but from the ExecutorService itself.

Upvotes: 0

Views: 1532

Answers (2)

Jackson Cassimiro
Jackson Cassimiro

Reputation: 527

You could use a custom class that implements Runnable with a collection of excpetions inside, like this:

public class MyRunnable implements Runnable {
    private List<Exception> exceptions;

    ...

    public void addException(Exception e) { ... }
    public void getExceptions(){ ... }
}

After all runnables finish their executions you could check for exceptions inside them and throw another exception in response.

Upvotes: 0

ericson
ericson

Reputation: 1658

The Executors.newCachedThreadPool creates a ThreadPoolExecutor with a unlimited maximum thread pool size(note the second argument of ThreadPoolExecutor constructor):

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

That means if you are submitting tasks faster than the consuming rate, new threads will be created for each new tasks, eventually it will reach the system limit and the "unable to create new native thread" exception is thrown.

To fix this, you need to change the configuration of ThreadPoolExecutor:

  1. Use a reasonable ThreadPoolExecutor.
  2. Choose a proper reject policy when the ThreadPoolExecutor is exhausted.

For example:

ExecutorService executorService = new ThreadPoolExecutor(5,200,
                          60L, TimeUnit.SECONDS,
                          new ArrayBlockingQueue(1000),
                          Executors.defaultThreadFactory(),
                          new ThreadPoolExecutor.CallerRunsPolicy());

Please read the JavaDocs for configuration details.

Upvotes: 3

Related Questions