3

我想在 AsyncTask.THREAD_POOL_EXECUTOR 上运行一些 AsyncTask。我正在使用以下代码。

Tasks[i].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
                                                              taskParams);

在向执行器发送一定数量的线程后,它不再接受新的 AsyncTasks。(我没有看到任何错误,但由于某种原因 doInBackGroundMethod 没有启动)。

我怀疑发生这种情况是因为它的池已满。有没有办法重置执行者?我想完全终止所有任务,以便它再次开始接受新任务并立即处理它们。

我尝试使用他们的取消方法终止任务,但它没有帮助。

4

2 回答 2

2

你的任务完成了吗?您是否正在处理适当的异常?您正在创建多少个任务?

请记住AsyncTask.THREAD_POOL_EXECUTOR(至少在API 17中;这个文档页面有很多有用的细节),设置为

public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

CORE_POOL_SIZE5 和MAXIMUM_POOL_SIZE128在哪里。

sPoolWorkQueue 与

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

这意味着队列的最大容量为 10 个项目。

THREAD_POOL_EXECUTOR 至少保持 5 个线程处于活动状态。随着任务的添加,它们被添加到队列中。当队列填满时,将产生新线程,最多 128 个(还有其他限制)。

当这种情况发生时(最多 128 个线程正在运行并且队列已满),任何新任务都将被拒绝,并使用默认处理程序进行处理(因为它没有被明确设置为 is AbortPolicy),这会引发RejectedExecutionException

确保您不只是捕获而不是处理此类异常。

解决此问题的一种方法是创建自己的ExecutorService(即使它只是具有不同参数的 ThreadPoolExecutor 实例)并配置最适合您情况的参数。队列等参数(您可以控制它可以容纳的项目数量,或者它是否无界等)或如何处理被拒绝的任务。

于 2013-10-09T06:07:17.807 回答
1

我可以看到取消 AsyncTasks 仍在运行的两个原因:

  • 要么你不打电话cancelmayInterruptIfRunningset totrue
  • 要么你调用AsyncTask.cancel(true),但InterruptedException被执行的代码错误处理:确保你的代码(以及对库的可能后续调用)不会InterruptedException通过 try/catch on InterruptedExceptions 甚至 on混淆/silence s Exception
于 2013-10-17T16:46:21.147 回答