Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RejectedExecutionException from AsyncTask, but haven't hit limits

My Android app has to deal with arriving messages which frequently come in bunches (especially during periods of flaky connectivity). I handle these incoming messages in AsyncTasks so that I don't interfere with the UI thread. If too many messages come in at once, I get a RejectedExecutionException. My error stack looks like this:

10-22 14:44:49.398: E/AndroidRuntime(17834): Caused by: java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@414cbe68 rejected from java.util.concurrent.ThreadPoolExecutor@412716b8[Running, pool size = 128, active threads = 22, queued tasks = 0, completed tasks = 1323]
10-22 14:44:49.398: E/AndroidRuntime(17834):    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1967)
10-22 14:44:49.398: E/AndroidRuntime(17834):    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:782)
10-22 14:44:49.398: E/AndroidRuntime(17834):    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1303)
10-22 14:44:49.398: E/AndroidRuntime(17834):    at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:564)

I'm running the tasks with task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) so that incoming messages are processed in parallel.

What is confusing about this, and different from related StackOverflow questions that I can find (e.g. here and here), is that the number of active threads and queued tasks don't seem to be bumping up against the limits (which seem to be 128 and 10, respectively). See the stacktrace:

ThreadPoolExecutor@412716b8[Running, pool size = 128, active threads = 22, queued tasks = 0, completed tasks = 1323]

Why would I be getting this error message?

like image 304
abeboparebop Avatar asked Oct 22 '13 22:10

abeboparebop


2 Answers

Why would I be getting this error message?

If the ThreadPoolExecutor is still running, you would get this error message only if you have exceeded the number of tasks that can be queued by the ThreadPoolExecutor. The only time the RejectedExecutionException is thrown is by the ThreadPoolExecutor.AbortPolicy which is the default RejectedExecutionHandler.

To quote from the javadocs:

If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.

There is a maximum number of tasks. See this question/answer here: Is there a limit of AsyncTasks to be executed at the same time?

Here's a link for the sourcecode for AsyncTask.

private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;

private static final BlockingQueue<Runnable> sWorkQueue =
        new LinkedBlockingQueue<Runnable>(10);

private static final ThreadPoolExecutor sExecutor =
    new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE,
        KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);

So it looks like it starts at 5 threads, has a queue of 10. Once the queue is full it can start up to 128 threads. So it looks like you have exceeded 138 simultaneous requests.

ThreadPoolExecutor@412716b8[Running, pool size = 128, active threads = 22, queued tasks = 0, completed tasks = 1323]

Trying to catch the ThreadPoolExecutor the exact moment that it runs out of space is going to be very hard and it will quickly turn into a heisenbug in that the more you look at the ThreadPoolExecutor numbers, the more you are going to affect the synchronization of that class and therefore you might make the bug go away.

In your case, by the time you get to log the exception with the details about the TPE, the condition must have passed.

like image 125
Gray Avatar answered Sep 28 '22 01:09

Gray


This exception also occur if your Executor call shutdown method and after that you give new Task (Runnable) for execution. Like

mThreadPoolExecutor.shutdown();
...
...
...
mThreadPoolExecutor.execute(new Runnable(){...});
like image 22
Hafiz Waleed Hussain Avatar answered Sep 27 '22 23:09

Hafiz Waleed Hussain