什么时候以及为什么要使用一组执行器

时间:2018-09-04 21:04:49

标签: 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)
    }
}
}

为什么要选择使用一组执行者?您仅凭一个执行者就无法实现这一目标?

1 个答案:

答案 0 :(得分:2)

这只是为可能执行的正确工作构造并分配正确的执行者:

  1. 很好地将它放在一个类中,以方便重用。
  2. 使用三种类型的执行程序,每种执行程序都可以执行特定类型的任务。请记住,执行者具有执行作业或Runnable的线程,并且执行者创建的每个线程可以一次运行一个作业:
    • diskIO是{来自constrcutor的{​​{1}},因为最好将任务一次排队并一次执行,以减少例如写入和读取锁定或竞争条件。因此,Executors.newSingleThreadExecutor()一次只能运行一项任务,无论有多少队列确保该设计。成为单个线程还可能意味着它例如用于将应用程序日志写入文件中,从而允许将日志以提交给执行者的正确顺序进行写入。因此,单线程最适合按作业排队的顺序维护输出。
    • SingleThreadExecutornetworkIO,因为任务通常与网络有关,例如连接到Internet上的服务器并执行请求或获取数据。这些任务通常会使用户等待(可能在几秒钟到几分钟之间),并且需要并行且快速地执行以缩短等待时间,以防万一需要同时执行许多请求。因此,此执行程序使用3个线程的原因是在其中分配任务并一起执行。这里的作业顺序不是问题,因为作业需要花费不同的时间来执行,但最重要的是它们并行运行。
    • Executors.newFixedThreadPool(3)mainThread,它在Android应用中用于处理UI并进行绘制。用户界面应运行平稳且不会滞后,因此,使用上述两个执行程序的原因是让任何繁重的任务(如编写文件或执行请求)在后台运行,或与应用程序的MainThreadExecutor()分开运行。即使应用程序未向其提交,该执行程序也会继续执行任务。它一直执行的任务是在不断重复的屏幕上连续绘制UI。 mainThread执行的任务需要轻巧,快速(花费的时间以毫秒为单位),因此会降低速度的任何任务都会被注意到,因为UI会滞后或出现故障,因为{{ 1}}忙于完成该任务,而不是绘制和更新UI。 mainThread在这里仅使用mainThread,它是Android SDK /体系结构的一部分,是单线程类型,其行为类似于执行程序(有一些区别),该执行程序将创建/更新UI的任务排队。只有mainThread可以执行UI任务,其他执行程序则不能。