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

我的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)运行任务,以便并行处理传入消息。

什么是令人困惑的,不同于我可以find的相关的StackOverflow问题(例如在这里和这里 ),是活动线程和排队任务的数量似乎没有碰到限制(这似乎是128和10)。 查看堆栈跟踪:

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

为什么我会收到这个错误信息?

Solutions Collecting From Web of "来自AsyncTask的RejectedExecutionException,但没有达到限制"

为什么我会收到这个错误信息?

如果您超出了ThreadPoolExecutor可以排队的任务数量,您将得到此错误消息。 抛出RejectedExecutionException的唯一时间是ThreadPoolExecutor.AbortPolicy ,它是默认的RejectedExecutionHandler

引用javadocs :

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

有最大数量的任务。 在这里看到这个问题/答案: 是否有限制的AsyncTasks同时执行?

这是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 [Running,pool size = 128,active threads = 22,queued tasks = 0,completed tasks = 1323]

试图抓住ThreadPoolExecutor时,空间耗尽的确切时刻将会变得非常困难,并且它会很快变成heisenbug ,因为看到ThreadPoolExecutor数字越多,影响同步的次数越多上课,因此你可能会让bug消失。

在你的情况下,当你用TPE的细节loggingexception时,条件必须已经通过。

如果您的执行程序调用closures方法,并在此之后您给新的任务(Runnable)执行,也会发生此exception。 喜欢

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