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

时间:2019-03-01 10:39:11

标签: android multithreading kotlin kotlin-coroutines

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

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

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

但实际结果是

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

单线程块#2和单线程块#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")
}

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") }

1 个答案:

答案 0 :(得分:1)

在代码中注意delay()suspend函数。它是通过协程悬架实现的。这意味着代码的执行在您调用delay时暂停,并且仅在超时后恢复。线程(例如,您通过async(singleThread) {..}使用的线程并不忙于等待时间过去。

总体情况如下

  • ...
  • 已打印“异步块#2”
  • 任务2正在singleThread
  • 上运行
  • 任务2已被delay(1500)暂停,singleThread是免费的
  • 任务1在singleThread
  • 上启动
  • 任务1被delay(500)暂停,singleThread是免费的
  • 那时,我们有了延迟队列:
    • 恢复任务1的delay(500)
    • 恢复任务2的delay(1500)
  • 一段时间后
  • resume(500)安排任务1的第二部分在singleThread中运行
  • 一段时间后
  • resume(1500)安排任务2的第二部分在singleThread中运行