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

后端 未结 3 1943
情歌与酒
情歌与酒 2020-12-31 05:14

In my Android project I had a lot of places where I need to run some code asynchronously (a web request, call to db etc.). This is not long running tasks (maximum a few seco

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-31 05:44

    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 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.

提交回复
热议问题