当前位置: 首页 > 知识库问答 >
问题:

静态编程语言延迟是否在内部使用调度程序来解除屏蔽调用线程?

甄文彬
2023-03-14

这是我用来学习kotlin协同程序的一些测试代码。代码按预期工作,大约需要1秒来打印总和,但现在如果我用阻塞调用(如网络请求)替换延迟(1000),那么代码大约需要10秒来打印总和(每个调用大约需要1秒),但如果我将网络调用包装在withContext中并使用IO调度程序,则需要1秒来打印总和,因为它是在不同的线程上运行的。延迟函数是否使用某种调度程序来解除线程阻塞?


suspend fun asyncDoubleFn(num: Int): Int {
    delay(1000)
    return num * 2
}


fun main() = runBlocking {
    launch {
        val tt = measureTimeMillis {
            val results = mutableListOf<Deferred<Int>>()
            for (num in 0..10) {
                val result = async { asyncDoubleFn(num + 1) }
                results.add(result)
            }
            val sum = results.map { it.await() }.reduce { acc, i -> acc + i }
            println("[SUM]: $sum")
        }

        println("[TT]: $tt")
    }


    launch {
        println("Another coroutine")
    }

    println("Main Code")


}

共有1个答案

饶德本
2023-03-14

延迟函数是否使用某种调度程序来解除线程阻塞?

不仅仅是延迟。所有可挂起的函数都与调度程序交互。

你应该问的问题是:“这里哪个调度员负责?”

答案是:runBlock安装自己的调度程序,该调度程序调度到它被调用的线程。代码中的启动async继承了它。

记住这一点:

如果我用网络请求等阻塞调用替换延迟(1000),那么代码大约需要10秒来打印总和(每个调用大约需要1秒)

每个阻塞调用将保留调度程序的单个线程。它将无法在被阻止时执行任何其他工作。

但是,如果我将网络调用包装在一个带有上下文的容器中,并使用IO调度程序,则需要1秒来打印总和,因为它是在不同的线程上运行的

是的,这改变了调度程序,问题解决了。

那么,延迟做什么呢?它挂起当前协同路由(异步启动的协同路由),并将控制返回给调度程序,调度程序现在可以继续恢复循环并启动下一个协同路由。

 类似资料:
  • 我正在尝试从我的Java类中调用此柯特林挂起代码。该解决方案基于此处提到的内容。https://stackoverflow.com/a/52887677/5140533 科特林代码: 当我从我的Java类调用时,我看不到任何print语句。有人能解释一下到底发生了什么以及我如何纠正这一点吗?

  • 所以我希望我的应用程序在一定的时间间隔内执行操作。在做了一点研究后,我在stackoverflow上找到了一些答案,它使我找到了这个链接,该链接称为固定RateTimer:这是该页面中的第一个示例 当我添加这段代码时,我得到了一个错误。 “表达式'fixedRateTimer'不能作为函数调用。找不到函数'invoke()'变量'fixedRateTimer'必须初始化” 我做了更多的研究并引进了

  • 我正在尝试使用柯特林 V1.2.70、Gradle V4.10.1 和 Java 11。使用 gradle 编译项目时,出现错误,指出“未知的 JVM 目标版本:11。支持的版本:1.6,1.8“。 Kotlin 编译器是否支持 Java 11(生成与 Java 11 JVM 兼容的代码)?如果是这样,如何使用渐变配置?

  • 我想为我的游戏创建一个简单的倒计时,当游戏开始时,我想每秒调用这个函数: 我试过这个: 但应用程序不幸停止,第二次调用run函数 3周前,我刚刚开始使用android开发和静态编程语言,到目前为止,我对它了解最多。 在Xcode中使用swift时,我使用了这一行,我认为类似的东西也适用于Kotlin

  • 我在kotlin文件中定义了这个函数。 想这样从Java调用它 随着 但它给了我 我意识到lambda函数的参数似乎是< code >列表 如果我把类转换成java,我可以很容易地用lambda回调函数调用那个函数。 我做错了什么

  • 问题内容: 我决定使自己熟悉node.js,并阅读有关该主题的几篇文章。我仍然不清楚的是,当您调用node.js函数时,node.js是否在线程池中创建新线程和/或在线程上调度任务。 例如,如果我调用它是否在其他线程上执行? 如果是,[如何]我可以编写自己的函数或在其他线程上运行? 问题答案: 没有用于文件操作的异步API,因此node.js为此使用了线程池。您可以在libuv的代码中看到它。 该