new Thread(task).start() VS ThreadPoolExecutor.submit(task) in Android new Thread(task).start() VS ThreadPoolExecutor.submit(task) in Android multithreading multithreading

new Thread(task).start() VS ThreadPoolExecutor.submit(task) in Android


This answer assumes your tasks are short

Is this kind of pattern better then creating new Threads in code?

It's better, but it's still far from ideal. You are still creating threads for short tasks. Instead you just need to create a different type of thread pool - for example by Executors.newScheduledThreadPool(int corePoolSize).

What's the difference in behaviour?

  • A FixedThreadPool will always have a set of threads to use and if all threads are busy, a new task will be put into a queue.
  • A (default) ScheduledThreadPool, as created by the Executors class, has a minimum thread pool that it keeps, even when idle. If all threads are busy when a new task comes in, it creates a new thread for it, and disposes of the thread 60 seconds after it is done, unless it's needed again.

The second one can allow you to not create new threads by yourself. This behaviour can be achieved without the "Scheduled" part, but you will then have to construct the executor yourself. The constructor is

public ThreadPoolExecutor(int corePoolSize,                          int maximumPoolSize,                          long keepAliveTime,                          TimeUnit unit,                          BlockingQueue<Runnable> workQueue)

The various options allow you to fine-tune the behaviour.

If some tasks are long...

And I mean long. As in most of your application lifetime (Realtime 2-way connection? Server port? Multicast listener?). In that case, putting your Runnable in an executor is detrimental - standard executors are not designed to cope with it, and their performance will deteriorate.

Think about your fixed thread pool - if you have 5 long-running tasks, then any new task will spawn a new thread, completely destroying any possible gains of the pool. If you use a more flexible executor - some threads will be shared, but not always.

The rule of thumb is

  • If it's a short task - use an executor.
  • If it's a long task - make sure your executor can handle it (i.e. it either doesn't have a max pool size, or enough max threads to deal with 1 more thread being gone for a while)
  • If it's a parallel process that needs to always run alongside your main thread - use another Thread.


To answer your question — Yes, using Executor is better than creating new threads because:

  1. Executor provides a selection of different thread pools. It allows re-use of already existing threads which increases performance as thread creation is an expensive operation.
  2. In case a thread dies, Executor can replace it with a new thread without affecting the application.
  3. Changes to multi-threading policies are much easier, as only the Executor implementation needs to be changed.


Based on the comment of Ordous I have modified my code to work with only one pool.

public class App extends Application {    private ThreadPoolExecutor mPool;    @Override    public void onCreate() {        super.onCreate();        mPool =  new ThreadPoolExecutor(5, Integer.MAX_VALUE, 1, TimeUnit.MINUTES, new SynchronousQueue<Runnable>());    }}public void submitRunnableTask(Runnable task){    if(!mPool.isShutdown() && mPool.getActiveCount() != mPool.getMaximumPoolSize()){        mPool.submit(task);    } else {        new Thread(task).start(); // Actually this should never happen, just in case...    }}

So, I hope this can be useful to someone else, and if more experienced people have some comments on my approach, I will very appreciate their comments.