新的线程(任务)。开始()VS ThreadPoolExecutor.submit(任务)中的机器人任务、线程、机器人、VS

2023-09-06 13:55:33 作者:[亡]

在我的Andr​​oid项目中,我有很多的,我需要异步运行约code(Web请求,调用数据库等)的地方。这不是长运行的任务(最大几秒)。 到现在为止我在做这种东西与创建一个新的线程,传递给它一个新的可运行的任务。但最近我看了一下线程和并发在Java中的文章,了解,创建一个新的线程为每一个任务不是一个好的决定。

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 seconds). Until now I was doing this kind of stuff with creating a new thread, passing it a new runnable with the task. But recently I have read an article about threads and concurrency in Java and understood that creating a new Thread for every single task is not a good decision.

所以,现在我已经创建了一个的ThreadPoolExecutor 在我的应用程序类,它包含5个线程。 这里是code:

So now I have created a ThreadPoolExecutor in my Application class which holds 5 threads. Here is the code:

public class App extends Application {

    private ThreadPoolExecutor mPool;

    @Override
    public void onCreate() {
        super.onCreate();

        mPool =  (ThreadPoolExecutor)Executors.newFixedThreadPool(5);
    }
}

和我也必须提交的Runnable任务的执行人方法:

And also I have a method to submit Runnable tasks to the executor:

public void submitRunnableTask(Runnable task){
    if(!mPool.isShutdown() && mPool.getActiveCount() != mPool.getMaximumPoolSize()){
        mPool.submit(task);
    } else {
        new Thread(task).start();
    }
}

所以,当我想在我的code运行异步任务,我得到应用实例并调用 submitRunnableTask 方法,将可运行它。正如你所看到的,我也检查,如果线程池中有空闲线程来执行我的任务,如果不是,我创建了一个新的线程(我不认为这会发生,但在任何情况下......我不吨要我的任务在队列中等待,减缓应用程序)。

So when I want to run an asynchronous task in my code I get the instance of App and call the submitRunnableTask method passing the runnable to it. As you can see, I also check, if the thread pool has free threads to execute my task, if not, I create a new Thread (I don't think that this will happen, but in any case... I don't want my task to wait in a queue and slow down the app).

onTerminate 回调的应用我关机方法游泳池。

In the onTerminate callback method of Application I shutdown the pool.

所以我的问题是:在code是这种模式的更好,然后创造新的主题?我的新方法有哪些优点和缺点?这可能会导致我不知道还关闭的问题?你能指点我的东西比这更好的来管理我的异步任务?

So my question is the following: Is this kind of pattern better then creating new Threads in code? What pros and cons my new approach has? Can it cause problems that I am not aware off yet? Can you advice me something better than this to manage my asynchronous tasks?

P.S。我在Android和Java的一些经验,但我远远不是一个并发大师),所以可能是有问题,我不这类问题非常了解。任何意见将AP preciated。

P.S. I have some experience in Android and Java, but I am far from being a concurrency guru ) So may be there are aspects that I don't understand well in this kind of questions. Any advice will be appreciated.

推荐答案

这个回答假设你的任务是短

这是一种模式更好,然后创造code新主题?

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

这是更好,但它仍然很不理想。您现在的仍然创造了短期任务的线程的。相反,你只需要创建一个不同类型的线程池 - 由 Executors.newScheduledThreadPool例如(INT corePoolSize)

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

什么是行为的区别?

A FixedThreadPool 总会有一组线程的使用,如果所有线程都很忙,一个新的任务将被放入队列中。 A(默认) ScheduledThreadPool ,由执行人类作为创建,拥有的最小,它保持线程池,即使处于空闲状态。如果所有线程都很忙,当一个新的任务到来时,的它创建为它的一个新的线程,该线程的处置它完成60秒后,除非它再次需要。 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.

如果有些任务是长...

和我的意思是长。在大多数应用程序生命周期中(实时2路连接?服务器端口?组播监听器?)。在这种情况下,把你的的Runnable 在执行者是不利的 - 标准的执行者的没有的设计,以应付它,他们的表现会恶化。

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.

想想你固定的线程池 - 如果你有5长时间运行的任务,那么任何新的任务将产生一个新的线程,彻底销毁池的任何可能的收益。如果您使用的是更灵活的执行者 - 部分线程将被共享,但并非总是如此。

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.

经验法则是

如果它是一个的短任务的 - 使用一个执行 如果它是一个的长期任务的 - 确保你的遗嘱执行人可以处理它(即它要么不具有最大池大小,或者足以最大线程处理1更多话题正在消失的而) 如果它是一个并行的过程,需要始终沿着你的主线程中运行 - 用另一个线程 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.
 
精彩推荐
图片推荐