AsyncTask 线程永不消亡
Posted
技术标签:
【中文标题】AsyncTask 线程永不消亡【英文标题】:AsyncTask threads never die 【发布时间】:2011-03-05 21:10:59 【问题描述】:我正在使用AsyncTask
s 来获取数据以响应用户按下按钮。这很好用,并且在获取数据时保持界面响应,但是当我检查 Eclipse 调试器中发生的事情时,我发现每次创建一个新的 AsyncTask
时(这很常见,因为它们只能使用一次),正在创建一个新线程但从未终止。
结果是大量的AsyncTask
线程只是坐在那里。我不确定这在实践中是否存在问题,但我真的很想摆脱那些额外的线程。
我怎样才能杀死这些线程?
【问题讨论】:
“永不终止”是什么意思?任务是永远不会结束它的 doInbackground 方法,还是只是在分配跟踪器中看到 asynctask 对象?doInBackground
方法完成,但线程继续显示在调试窗口中。例如:Thread [<23> AsyncTask #4](Running)
【参考方案1】:
AsyncTask
管理一个使用ThreadPoolExecutor
创建的线程池。它将有 5 到 128 个线程。如果线程数超过 5 个,则这些多余的线程最多会停留 10 秒,然后才会被移除。 (注意:这些数字是针对目前可见的开源代码,因 android 版本而异)。
请不要使用AsyncTask
线程。
【讨论】:
感谢您的解释!我很高兴知道我没有做错任何事。出于好奇,为什么要这样设计?为什么不在所有方法都返回后结束线程? 大概是为了节省在后续请求中分叉线程的时间。 @CommonsWare 我有一个服务,我在其中运行 AsyncTask 来执行一些操作,当按下小部件按钮时服务启动,当任务完成时它必须立即停止服务,但是有时 AsyncTask 不会死,你能告诉我如何停止它 @SreekanthKarumanaghat:一般来说,使用AsyncTask
来处理需要这么长时间的事情是个坏主意。但是不,我对多余线程消失的评论是当它们未被使用时。因此,当您的 6 个任务之一结束时,其线程将在池中保留 10 秒,之后该线程将被终止。
@SreekanthKarumanaghat:“我的问题是并行运行 20 个(比如说)AsyncTasks 是否有任何限制?” -- 今天大量使用AsyncTask
并不是一个好计划。有 20+ 可能运行 10+ 秒是那种应该使代码审查失败的事情。如果你快速连续创建 20 个任务,一次只会运行几个,其余的将排队等待稍后执行。一次运行多少个取决于 CPU 的核心数。 AFAIK,当前算法是 2N+1 并行线程,其中 N 是内核数。【参考方案2】:
除了 CommonsWare 的回应:
目前我使用的是 Android 2.2,我的应用程序在任何时候都使用不超过一个 AsyncTask,但我每 x 分钟创建一个新任务。起初,新的 AsyncTask 线程开始出现(新 AsyncTask 的新线程),但在 5 个线程之后(如 CommonsWare 所述),它们只会在调试窗口中保持可见,并在需要新的 AsyncTask 线程时重新使用。他们只是呆在那里直到调试器断开连接。
【讨论】:
是的,确认:我看到的 AsyncTask 不超过 5 个。【参考方案3】:这里有同样的症状。在我的情况下,线程在我杀死 Activity 后仍然存在,我希望应用程序完全关闭。通过使用单线程执行程序部分解决了问题:
myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());
这使得线程在完成工作后消失了。
【讨论】:
这个答案使 AsyncTask 在运行后消失了,也许它不是“谷歌做事的方式”,但它完成了工作。谢谢。 这解决了我在单线程上运行 Asynctasks 的具体问题。【参考方案4】:使用ThreadPoolExecutor。
BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(), // Initial pool size
Runtime.getRuntime().availableProcessors(), // Max pool size
1, // KEEP_ALIVE_TIME
TimeUnit.SECONDS, // KEEP_ALIVE_TIME_UNIT
workQueue);
使用execute() 方法发布您的Runnable
任务。
void execute (Runnable command)
在未来的某个时间执行给定的任务。该任务可能在新线程或现有池线程中执行
关于您的第二个查询:
我怎样才能杀死这些线程?
一旦您完成了与 ThreadPoolExecutor
的所有工作,请按照以下帖子中的引用正确关闭它:
How to properly shutdown java ExecutorService
【讨论】:
以上是关于AsyncTask 线程永不消亡的主要内容,如果未能解决你的问题,请参考以下文章