何时以及为什么会使用一组 Executor

4 android

我一直在阅读 Android 文档中关于 Executor 的内容。如果我理解正确的话,它用于多线程管理,它会为您完成一些工作,例如在需要时生成新线程。或者你可以选择自己管理东西。

在下面的示例中,使用一组执行程序而不是一个执行程序。所以它就像一个线程池(?)。

/**
* Global executor pools for the whole application.
*
* Grouping tasks like this avoids the effects of task starvation (e.g. disk 
reads don't wait behind
* webservice requests).
*/
@Singleton
open class AppExecutors(
private val diskIO: Executor,
private val networkIO: Executor,
private val mainThread: Executor
) {

@Inject
constructor() : this(
    Executors.newSingleThreadExecutor(),
    Executors.newFixedThreadPool(3),
    MainThreadExecutor()
)

fun diskIO(): Executor {
    return diskIO
}

fun networkIO(): Executor {
    return networkIO
}

fun mainThread(): Executor {
    return mainThread
}

private class MainThreadExecutor : Executor {
    private val mainThreadHandler = Handler(Looper.getMainLooper())
    override fun execute(command: Runnable) {
        mainThreadHandler.post(command)
    }
}
}
Run Code Online (Sandbox Code Playgroud)

为什么会选择使用一组执行器?你用它实现了什么,而你不能只用一个执行器?

aha*_*ini 7

这只是为他们可能执行的正确作业构建和分配正确的执行器:

  1. 它很好地放在一个类中,以便于重用。
  2. 使用了三种类型的执行器,每一种都用于它可以运行的特定类型的任务。请记住,执行程序有线程来执行作业或Runnables,执行程序创建的每个线程一次可以运行一项作业:
    • diskIOis (from the constrcutor) aExecutors.newSingleThreadExecutor()因为任务最好排队并一次执行一个,以减少读写锁或竞争条件。因此,SingleThreadExecutor无论有多少任务排队以确保设计,一次都只会运行一个任务。作为单线程也可能意味着它被用于将应用程序日志写入文件,例如,它允许在提交给执行程序时以正确的顺序写入日志。因此,单线程最适合按照排队的作业顺序维护输出。
    • networkIOExecutors.newFixedThreadPool(3)因为任务通常与网络相关,例如连接到 Internet 上的服务器并执行请求或获取数据。这些任务通常会让用户等待(可能在几秒到几分钟之间)并且需要并行且快速地执行以缩短等待时间,以防需要一起执行多个请求。因此,此执行器使用 3 个线程的原因是在它们之间分配任务并一起执行。作业顺序在这里不是问题,因为作业需要不同的时间来执行,但最重要的是它们是并行运行的。
    • mainThreadMainThreadExecutor()在 Android 应用程序中处理 UI 并绘制它的。UI 应该运行流畅而不滞后,因此使用上述两个执行程序的原因是让任何繁重的任务(如编写文件或执行请求)在后台运行或与mainThread应用程序分开运行。即使应用程序没有向它提交任何任务,该执行程序也会继续执行任务。它不断执行的任务是在不断重复的屏幕上不断绘制 UI。mainThread需要轻量级和快速执行的任务(它们花费的时间以毫秒为单位),因此任何减慢它的任务都会被注意到,因为 UI 会滞后或出现故障,因为它mainThread正忙于完成该任务而不是绘制和更新 UI。在mainThread这里简单的使用Handler它是 Android SDK/架构的一部分,属于单线程类型,其行为类似于一个执行器(有一些差异),它将任务排队以创建/更新 UI。只有 aHandler可以执行 UI 任务,其他执行器都不能。

  • 您将如何决定 networkIO 的线程数?为什么不是,例如,2 或 4? (2认同)