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

abe*_*bop 17 multithreading android

我的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)
Run Code Online (Sandbox Code Playgroud)

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

令人困惑的是,与我能找到的相关StackOverflow问题(例如此处此处)不同的是,活动线程和排队任务的数量似乎没有超出限制(似乎是128)和10,分别).查看stacktrace:

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

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

Gra*_*ray 28

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

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

引用javadocs:

如果请求无法排队,则会创建一个新线程,除非它超过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);
Run Code Online (Sandbox Code Playgroud)

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

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

试图抓住ThreadPoolExecutor它耗尽空间的确切时刻将变得非常困难,并且很快就变成了一个heisenbug,因为你看到的ThreadPoolExecutor数字越多,你就越会影响该类的同步和因此你可能会让虫子消失.

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


Haf*_*ain 10

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

mThreadPoolExecutor.shutdown();
...
...
...
mThreadPoolExecutor.execute(new Runnable(){...});
Run Code Online (Sandbox Code Playgroud)