为后端应用程序设置 kotlin 协程作用域的正确方法

Ant*_*onK 3 kotlin kotlinx.coroutines

设置协程范围的正确方法是什么 -

一、实施范围

@Service
class MyServiceImpl : MyService, CoroutineScope {
    private val job: Job = Job()
    override val coroutineContext: CoroutineContext
        get() = job + Executors.newFixedThreadPool(100).asCoroutineDispatcher()
    override fun get(): String {
        launch {....}
        return "Result"
    }}
Run Code Online (Sandbox Code Playgroud)

` 2. 未实施

@Service
class MyServiceImpl : MyService {
    private val scope = Executors.newFixedThreadPool(100).asCoroutineDispatcher()
    override fun get(): String {
        GlobalScope.launch(scope) {....}
        return "Result"
    }}
Run Code Online (Sandbox Code Playgroud)

或者只是在没有任何上下文的情况下使用 GlobalScope ?

Ren*_*ene 5

没有正确的方法,所有三种变体在不同的场景中都有用。

  1. 实现自己的协程范围:如果您的协程的生命周期取决于另一个对象的生命周期。在 UI 应用程序中特别有用,例如 Android,如果您需要销毁所有待处理的协程,则当启动 Activity 被销毁时,请参阅https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide- ui.md#structed-concurrency-lifecycle-and-coroutine-parent-child-hierarchy
  2. 从线程池创建范围:如果您的协程应在公共线程池中运行。在这种情况下,新协程的生命周期不取决于此范围,而是取决于外部协程:

    val fixedThreadPoolContext = newFixedThreadPoolContext(100, "background")
    launch(Dispatchers.Main) {
        withContext(fixedThreadPoolContext) {
            //parent job is from the outer coroutine
        }
        //or
        val asyncResult = async(fixedThreadPoolContext) {
            //parent job is from the outer coroutine
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用全局范围:如果您想启动一些不依赖于任何其他对象的后台协程。通常,最好提供一个绑定到您的应用程序对象或某些全局单例的自己的范围。然后你可以提供自己的异常处理程序等

对于后端服务,我将使用自己的全局线程池调度程序然后您可以控制大小。请注意,GlobalScope 使用 CPU 计数作为参数来定义池大小。这对于 CPU 受限的任务来说非常有用,但对于 IO 任务(例如数据库访问)来说则不然。