112

I'm using AsyncTasks to fetch data in response to the user pressing a button. This works well and keeps the interface responsive while fetching the data, but when I checked out what was going on in the Eclipse debugger, I found out that every time a new AsyncTask was created (which is quite often, because they can only be used once), a new thread was being created but never terminated.

The result is a large number of AsyncTask threads just sitting there. I'm not sure if this is a problem in practice or not, but I'd really like to get rid of those extra threads.

How can I kill these threads?

Jonathan Soifer
  • 2,715
  • 6
  • 27
  • 50
Computerish
  • 9,590
  • 7
  • 38
  • 49
  • What do you mean with "never terminated"? Does the task never end its doInbackground method or do you just see the asynctask object in the allocation traker? – Francesco Laurita Jun 19 '10 at 22:29
  • 7
    The `doInBackground` method completes, but the thread continues to show up in the debug window. For example: `Thread [<23> AsyncTask #4](Running)` – Computerish Jun 20 '10 at 02:35

4 Answers4

202

AsyncTask manages a thread pool, created with ThreadPoolExecutor. It will have from 5 to 128 threads. If there are more than 5 threads, those extra threads will stick around for at most 10 seconds before being removed. (note: these figures are for the presently-visible open source code and vary by Android release).

Leave the AsyncTask threads alone, please.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks for the explanation! I'm glad to know that I'm not doing anything wrong. Out of curiosity, why is it designed like that? Why not just end the threads after all of the methods have returned? – Computerish Jun 20 '10 at 02:38
  • 7
    Presumably to save time forking the threads on later requests. – CommonsWare Jun 20 '10 at 11:26
  • @CommonsWare i have a service in which i am running a AsyncTask to perform some operation and the service starts when the widget button is being pressed and when the task is finished it must stop the servie immediately , but sometimes AsyncTask wont die ,so can u tell me how do i stop it – Hunt May 22 '13 at 16:48
  • so what to do if i use AsyncTask to download something (song,video,etc) and the end user is hungry for download thinking it's a torrent like app and manager blames me? – Ahmad Dwaik 'Warlock' Sep 30 '13 at 12:51
  • what about message like "Skipped * frames! The application may be doing too much work on its main thread." –  Feb 15 '16 at 08:30
  • Does this mean that, if I run 6 AsyncTasks parallely, the 6th one will be removed automatically after 10 seconds? If yes what is the solution for this problem? – Sreekanth Karumanaghat Feb 16 '18 at 11:07
  • 1
    @SreekanthKarumanaghat: Using an `AsyncTask` for something that would take that long is a bad idea in general. But no, my comment about the extra threads going away are when they are unused. So, when one of your 6 tasks ends, its thread will remain in the pool for 10 seconds, after which that thread will be terminated. – CommonsWare Feb 16 '18 at 11:34
  • @CommonsWare My question is whether is there any restriction for running 20 (say) AsyncTasks in Parallel? – Sreekanth Karumanaghat Feb 16 '18 at 11:35
  • Also See https://stackoverflow.com/questions/48809781/android-app-crashing-due-to-thread-rejectedexecution-issue#comment84622831_48809781 – Sreekanth Karumanaghat Feb 16 '18 at 11:36
  • 1
    @SreekanthKarumanaghat: "My question is whether is there any restriction for running 20 (say) AsyncTasks in Parallel?" -- making significant use of `AsyncTask` today is not a great plan. Having 20+ that may run for 10+ seconds is the sort of thing that should fail a code review. If you create 20 tasks in rapid succession, only a few will run at once, and the rest will be queued for later execution. How many will run at once is based on the number of cores of the CPU. AFAIK, the current algorithm is 2N+1 parallel threads, where N is the number of cores. – CommonsWare Feb 16 '18 at 11:40
24

In addition to CommonsWare's response:

Currently I'm using Android 2.2, and my application uses no more than one AsyncTask at any time, but I'm creating a new one every x minutes. At first new AsyncTask Threads start to appear (a new Thread for a new AsyncTask) but after 5 threads (as mentioned by CommonsWare) they just stay visible in the debug window, and get re-used when new AsyncTask threads are needed. They just stay there until the debugger disconnects.

Tom de Waard
  • 373
  • 2
  • 7
4

Same symptom here. In my case the threads hanged around after I'd killed the Activity, and I was hoping for the App to close completely. Problem partly solved by using a single threaded executor:

    myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());

This made the thread to vanish after the completing its work.

karnbo
  • 191
  • 6
0

Use 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);

Post your Runnable task by using execute() method.

void execute (Runnable command)

Executes the given task sometime in the future. The task may execute in a new thread or in an existing pooled thread

Regarding your second query:

How can I kill these threads?

Once you are done with all your work with ThreadPoolExecutor, shutdown it properly as quoted in below post:

How to properly shutdown java ExecutorService

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211