来自AsyncTask的RejectedExecutionException,但没有达到限制

时间:2013-10-22 22:10:52

标签: android multithreading

我的Android应用程序必须处理到达的消息,这些消息经常串联(特别是在片状连接期间)。我在AsyncTasks中处理这些传入的消息,这样我就不会干扰UI线程。如果一次收到太多邮件,我会收到RejectedExecutionException。我的错误堆栈如下所示:

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)

我正在使用task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)运行任务,以便并行处理传入的消息。

令人困惑的是,与我可以找到的相关StackOverflow问题(例如herehere)不同的是,活动线程和排队任务的数量似乎不是碰到极限(分别为128和10)。请参阅stacktrace:

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

为什么我会收到此错误消息?

2 个答案:

答案 0 :(得分:28)

  

为什么我会收到此错误消息?

如果您已超过ThreadPoolExecutor可排队的任务数,则会收到此错误消息。 RejectedExecutionException被抛出的唯一时间是ThreadPoolExecutor.AbortPolicy,这是默认的RejectedExecutionHandler

引用javadocs

  

如果请求无法排队,则会创建一个新线程,除非这会超过maximumPoolSize,在这种情况下,该任务将被拒绝。

有最多的任务。在此处查看此问题/答案:Is there a limit of AsyncTasks to be executed at the same time?

以下是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);

所以看起来它从5个线程开始,队列为10.一旦队列已满,它就可以启动最多128个线程。所以看起来你已经超过了138个同时请求。

  

ThreadPoolExecutor @ 412716b8 [正在运行,池大小= 128,活动线程= 22,排队任务= 0,已完成任务= 1323]

试图抓住ThreadPoolExecutor它用完空间的确切时刻将非常困难,并且它会很快变成heisenbug,因为你看{{1} {{1}数字越多,你就会越多地影响该类的同步,因此你可能会让错误消失。

在您的情况下,当您使用有关TPE的详细信息记录异常时,条件必须已通过。

答案 1 :(得分:10)

如果您的Executor调用shutdown方法,并且之后您将执行新的Task(Runnable),也会发生此异常。 喜欢

mThreadPoolExecutor.shutdown();
...
...
...
mThreadPoolExecutor.execute(new Runnable(){...});