AsyncTask线程永不消亡


112

我正在使用 AsyncTask s来获取数据,以响应用户按下按钮。这样可以很好地工作,并在获取数据时使接口保持响应,但是当我检查Eclipse调试器中发生的情况时,我发现每次AsyncTask创建新程序时(这很常见,因为它们只能使用一次) ),正在创建一个新线程,但从未终止。

结果是大量 AsyncTask线程就坐在那儿。我不确定这在实践中是否存在问题,但是我真的很想摆脱那些多余的线程。

如何杀死这些线程?


“永不终止”是什么意思?任务永远不会结束其doInbackground方法,还是只在分配器中看到asynctask对象?
Francesco Laurita 2010年

7
doInBackground方法完成了,但是线程继续显示在调试窗口中。例如: Thread [<23> AsyncTask #4](Running)
Computerish 2010年

Answers:


202

AsyncTask 管理创建的线程池 ThreadPoolExecutor。它将具有5到128个线程。如果有5个以上的线程,那么这些多余的线程将最多保留10秒钟,然后再将其删除。(注意:这些数字是针对当前可见的开放源代码,并且因Android版本而异)。

请不要理会AsyncTask线程。


感谢您的解释!我很高兴知道我没有做错任何事情。出于好奇,为什么要这样设计?为什么不在所有方法返回后才结束线程?
Computerish 2010年

7
大概是为了节省在以后的请求上派发线程的时间。
CommonsWare 2010年

@CommonsWare我有一个服务,其中我正在运行AsyncTask来执行一些操作,并且该服务在按下小部件按钮时启动,并且当任务完成时必须立即停止服务,但有时AsyncTask不会死,所以您可以吗?告诉我我如何停止它
狩猎

1
@SreekanthKarumanaghat:使用an AsyncTask花费那么长的时间通常是个坏主意。但是不,我对多余线程消失的评论是未使用时。因此,当您的6个任务之一结束时,其线程将在池中保留10秒钟,此后该线程将被终止。
CommonsWare

1
@SreekanthKarumanaghat:“我的问题是在并行运行20个(例如)AsyncTasks是否有任何限制?” -充分利用AsyncTask今天并不是一个好计划。具有20多个可能运行10秒钟以上的时间是应该使代码审查失败的事情。如果快速连续创建20个任务,则一次只能运行几个任务,其余的将排队等待以后执行。一次可运行的数量取决于CPU的内核数量。AFAIK,当前算法是2N + 1个并行线程,其中N是内核数。
CommonsWare

24

除了CommonsWare的回复:

目前,我使用的是Android 2.2,我的应用程序在任何时候都使用不超过一个AsyncTask,但是我每x分钟创建一个新的AsyncTask。最初,新的AsyncTask线程开始出现(新的AsyncTask的新线程),但是在5个线程(如CommonsWare提到的)之后,它们仅在调试窗口中可见,并在需要新的AsyncTask线程时重新使用。他们只是呆在那里,直到调试器断开连接。


2
是的,已确认:我看到的AsyncTasks不超过5个。
塞拉芬

3

同样的症状在这里。以我为例,线程在我杀死了Activity之后仍然闲荡,我希望该应用程序完全关闭。通过使用单线程执行程序可以部分解决问题:

    myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());

这使线程在完成工作后消失。


这个答案使AsyncTask在运行后消失了,这也许不是“ google的做事方式”,但它可以完成工作。谢谢。
Henrique de Sousa 2014年

这解决了我关于在单个线程上运行Asynctasks的特定问题。
Law Gimenez

0

使用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);

Runnable通过使用execute()方法发布任务 。

void execute (Runnable command)

在将来的某个时间执行给定的任务。该任务可以在新线程或现有池线程中执行

关于第二个查询:

如何杀死这些线程?

使用完所有工作后ThreadPoolExecutor,请按照以下文章中的引用正确关闭它:

如何正确关闭Java ExecutorService

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.