Kotlin 协程:单线程中一次一个协程

Vin*_*.TV 5 multithreading android kotlin kotlin-coroutines

考虑下面的代码,我试图用它Executors.newFixedThreadPool(1).asCoroutineDispatcher()来创建一个单线程调度程序;我希望其中的代码launch(singleThread){...}按顺序执行

预期结果应该如下所示,因为 async-block#2首先到达/获取singleThread

异步块#2
异步块#1
单线程块#2
单线程块#1
答案是3

但实际结果是

异步块#2
异步块#1
单线程块#1
单线程块#2
答案是3

single-thread-block-#2 和 single-thread-block-#1 似乎并行运行,singleThread在这里没有什么不同

import java.util.concurrent.Executors
import kotlinx.coroutines.*
import kotlin.system.*

val singleThread = Executors.newFixedThreadPool(1).asCoroutineDispatcher()

fun main() = runBlocking<Unit> {
    val time = measureTimeMillis {
        val one = async { // async block #1
            delay(200)
            println("async block #1")
            launch (singleThread) {
                delay(500)
                println("single thread block #1")
            }
            2
        }
        val two = async { // async block #2
            delay(100)
            println("async block #2")
            launch (singleThread) {
                delay(1500)
                println("single thread block #2")
            }
            1
        }
        println("The answer is ${one.await() + two.await()}")
    }
    println("Completed in $time ms")
}
Run Code Online (Sandbox Code Playgroud)

Eug*_*nko 6

注意代码中的delay()is函数。suspend它是通过协程悬挂来实现的。这意味着代码的执行在您调用时暂停delay,只有在超时后才恢复。该线程(例如您使用 via 的线程)async(singleThread) {..}并不忙于等待时间流逝。

整体场景是这样的

  • ...
  • 打印的“async block #2”
  • 任务 2 正在运行singleThread
  • 任务 2 已暂停delay(1500),且singleThread空闲
  • 任务 1 开始于singleThread
  • 任务 1 被暂停delay(500),并且singleThread空闲
  • 此时我们就有了延迟队列:
    • 恢复delay(500)任务 1
    • 恢复delay(1500)任务 2
  • 一段时间后
  • resume(500)安排任务 1 的第二部分在singleThread
  • 一段时间后
  • resume(1500)安排任务 2 的第二部分在singleThread