首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Kotlin协同线:在单线程中一次一个协同线

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

Stack Overflow用户
提问于 2019-03-01 10:39:10
回答 2查看 5.2K关注 0票数 5

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

预期的结果应该如下所示,因为异步块#2首先到达/获取singleThread。

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

但实际结果是

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

单线程块#2和单线程块#1似乎是并行运行的,singleThread在这里没有什么不同。

代码语言:javascript
运行
复制
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")
}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-01 11:21:14

请注意,代码中的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)计划在singleThread中运行任务1的第二部分
  • 过了一段时间
  • resume(1500)计划在singleThread中运行任务2的第二部分
票数 6
EN

Stack Overflow用户

发布于 2021-12-27 21:21:16

除了@EugenePetrenko的答案之外,这是一个新的方法CoroutineDispatcher.limitedParallelism(numberOfParallelism),您可以使用它来保证并行性限制--最多可以在这个调度程序中并发执行一个协同。它将看起来像:

代码语言:javascript
运行
复制
val singleThread = Dispatchers.IO.limitedParallelism(1)

someCoroutineScope.launch (singleThread) {
    ...
}

函数limitedParallelism可以从1.6.0版本的kotlinx.coroutines库开始。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54942872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档