我的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问题(例如here和here)不同的是,活动线程和排队任务的数量似乎不是碰到极限(分别为128和10)。请参阅stacktrace:
ThreadPoolExecutor@412716b8[Running, pool size = 128, active threads = 22, queued tasks = 0, completed tasks = 1323]
为什么我会收到此错误消息?
答案 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(){...});