gpt4 book ai didi

java - Android 中的新 Thread(task).start() VS ThreadPoolExecutor.submit(task)

转载 作者:IT老高 更新时间:2023-10-28 23:40:35 26 4
gpt4 key购买 nike

在我的 Android 项目中,我有很多地方需要异步运行一些代码(网络请求、对数据库的调用等)。这不是长时间运行的任务(最多几秒钟)。到目前为止,我一直在做这种事情,创建一个新线程,将一个新的可运行对象传递给该任务。但最近我读了一篇关于 Java 中的线程和并发的文章,并明白为每个任务创建一个新线程并不是一个好的决定。

所以现在我在我的 Application 类中创建了一个 ThreadPoolExecutor,它拥有 5 个线程。这是代码:

public class App extends Application {

private ThreadPoolExecutor mPool;

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

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

而且我还有一种方法可以将 Runnable 任务提交给执行器:

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

因此,当我想在我的代码中运行异步任务时,我会获取 App 的实例并调用 submitRunnableTask 方法,将 runnable 传递给它。如您所见,我还检查了线程池是否有空闲线程来执行我的任务,如果没有,我创建一个新线程(我认为这不会发生,但无论如何......我没有'不希望我的任务在队列中等待并减慢应用程序的速度)。

在应用程序的 onTerminate 回调方法中,我关闭了池。

所以我的问题如下:这种模式是否比在代码中创建新线程更好?我的新方法有什么优点和缺点?它会导致我还没有意识到的问题吗?你能给我一些比这更好的建议来管理我的异步任务吗?

附:我在 Android 和 Java 方面有一些经验,但我远不是并发专家)所以在这类问题中可能存在我不太了解的方面。任何建议将不胜感激。

最佳答案

此答案假设您的任务很短

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

它更好,但仍远非理想。您仍在为短任务创建线程。相反,您只需要创建不同类型的线程池 - 例如通过 Executors.newScheduledThreadPool(int corePoolSize)

行为上有什么不同?

  • FixedThreadPool 将始终有一组线程可供使用,如果所有线程都忙,则会将新任务放入队列中。
  • Executors 类创建的(默认)ScheduledThreadPool 有一个保持的最小 线程池,即使在空闲时也是如此。如果有新任务进入时所有线程都忙,它会为其创建一个新线程,并在完成后 60 秒释放线程,除非再次需要它。

第二个可以让你不自己创建新线程。这种行为可以在没有“Scheduled”部分的情况下实现,但是您必须自己构建执行器。构造函数是

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

各种选项可让您微调行为。

如果有些任务很长...

我的意思是长。与您的应用程序生命周期的大部分时间一样(实时 2 路连接?服务器端口?多播监听器?)。在这种情况下,将您的 Runnable 放在执行器中是有害的 - 标准执行器不是为了应对这种情况而设计的,它们的性能会下降。

想想你的固定线程池——如果你有 5 个长时间运行的任务,那么任何新任务都会产生一个新线程,完全破坏池中任何可能的 yield 。如果您使用更灵活的执行器 - 一些线程将被共享,但并非总是如此。

经验法则是

  • 如果是短任务 - 使用执行器。
  • 如果它是一个长任务 - 确保你的执行器可以处理它(即它要么没有最大池大小,要么没有足够的最大线程来处理另外 1 个线程消失了同时)
  • 如果它是一个需要始终与主线程一起运行的并行进程 - 请使用另一个线程。

关于java - Android 中的新 Thread(task).start() VS ThreadPoolExecutor.submit(task),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26763835/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com