Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to shutdown executorservice in android application

Lets assume I'm planning to use one executorservice in my entire application, to which I'm sending new runnable's or callable's to execute/submit, and I ommit to shutdown right after I do that. I just want to throw my "tasks" to the executorservice and let him handle them and execute them giving it's resources (how many threads he has available, and how many he can create if needed and then queue those tasks accordingly).

From your experience of using ExecutorService in Android application, and taking into account the application state changes, if I don't want to constantly shutdown and re-create the executorservice by doing this:

    executor = Executors.newCachedThreadPool();
    executor.submit(some Runnable);
    executor.shutdown();

, what time and where would you reccomend to shutdown service, and then reinstate it so that I can prevent some leaks or some unforseen consequences?

I'm mostly reffering to:

1) Closing app by back button on the last activity in the backstack (Application uses many activities) 2) Application going in the background (on any of those activities) 3) Application going back into foreground (on any of those activities)

like image 646
Lucas Avatar asked May 01 '13 10:05

Lucas


2 Answers

You can do one work around. Create the executor as daemon. Then it will automatically end when your application exits. You don't have to explicitly call the shutdown.

 ExecutorService es = Executors.newSingleThreadExecutor( new ThreadFactory() {
    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
});
like image 139
Manu Viswam Avatar answered Sep 20 '22 23:09

Manu Viswam


I have a singleton instance of an ExecutorService which is scoped to the Android application instance via Dagger's object graph. So the instance lives as long as the Application object itself. Since Android's Application class offers no onDestroy() callback, it is never known when shutdown() should be called on the ExecutorService.

As I was afraid of memory leaks, I was also looking into ThreadPoolExecutor and playing with it to find out. This is what I found: Executors.newCachedThreadPool() creates a ThreadPoolExecutor with the following parameters:

ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>())

That is a corePoolSize of 0, which means that a minimum number of 0 worker threads is kept alive, so none. When the TPE (a.k.a ExecutorService) executes a task, it creates a worker thread and adds it to the pool. Now when no new task comes in during the timeout of 60 secs, the (still kept alive) worker thread is terminated and removed from the pool (cache).

For me that means that there won't be a memory leak, even when shutdown() is never called on the ExecutorService, as all worker threads that ever exist, time out and will be removed from the pool when no new task come in during the timeout period. I guess that that way, there wont be any references to worker threads left in the pool and so the GC can clean up the TPE instance.

Feel free to correct me if I'm wrong.

like image 31
Sebastian Engel Avatar answered Sep 16 '22 23:09

Sebastian Engel