【问题标题】:CoRoutine Async is not running parallelyCoRoutine Async 未并行运行
【发布时间】:2020-10-10 08:08:29
【问题描述】:

我有以下代码,我正在尝试并行运行协程。但是,代码不会并行运行。所有股票价格返回需要 30 秒,而不是 10 秒。但是,如果我使用 GlobalScope.launch,它确实可以正常工作。我从文档中收集到我们应该避免使用 GlobalScope 并使用协程范围。你能帮助理解为什么这不是并行运行吗?

import kotlinx.coroutines.*

suspend fun getStockPrice(company: String) : Int{
    println("Fetching Stock Price")
    Thread.sleep(10000)
    return 100
}



fun CoroutineScope.launchCoRoutines() {
    val companies = listOf<String>("Google", "Amazon", "Microsoft")

    launch {

        var startTime = System.currentTimeMillis()
        val sharePrice = mutableListOf<Deferred<Int>>()
        for (company in companies) {
            sharePrice += async {
                getStockPrice(company).toInt()
            }
        }

        for (share in sharePrice) {
            println(share.await())
        }
        var endTime = System.currentTimeMillis()

        println(endTime - startTime)

    }


}

 fun main()  {
     runBlocking{
         launchCoRoutines()
     }
     println("Request Sent")
    Thread.sleep(55000)
}

【问题讨论】:

  • 你在主线程上运行你的协程,Thread.sleep(10000) 阻塞了它。将Thread.sleep 更改为delay,它会挂起线程而不是阻塞它。
  • 使用asyncDispatchers.IO async(Dispatchers.IO) { getStockPrice(company) }
  • @IR42 你能详细说明一下吗?

标签: kotlin kotlin-coroutines


【解决方案1】:

答案可以在这里找到:

Kotlin: coroutineScope is slower than GlobalScope

如前所述:

coroutineScope 没有定义自己的调度器,所以你继承它 来自调用者,在本例中是由 runBlocking 创建的。它用 调用它的单线程。

编辑: 你可以使用这个功能

fun launchCoRoutines() {
    val companies = listOf<String>("Google", "Amazon", "Microsoft")

    launch(Dispatchers.Default) { // will get dispatched to DefaultDispatcher 

        var startTime = System.currentTimeMillis()
        val sharePrice = mutableListOf<Deferred<Int>>()
        for (company in companies) {
            sharePrice += async {
                getStockPrice(company).toInt()
            }
        }

        for (share in sharePrice) {
            println(share.await())
        }
        var endTime = System.currentTimeMillis()

        println(endTime - startTime)
    }
}

编辑 2: 见@Animesh Sahu 评论,这是最好的答案

【讨论】:

  • 我不确定我明白了。如果我必须用协程上下文重写它,我该如何重写它以获得更好的性能? @benjiiii
  • @jagannathanrajagopalan 不要使用 Thread.sleep 并使用 suspend fun main() = coroutineScope {...} 而不是 runBlocking
  • 感谢@AnimeshSahu 的回复。有用。您能否提供任何解释此概念的文档/书籍/视频?
  • 正如@AnimeshSahu 所说,您不应该使用 Thread.sleep 也不应该使用 runBlocking。另外,请参阅我的编辑,您可以将 launch {} 替换为 lauch{Dispatchers.Default} 以在另一个线程上调度您的协程
  • @jagannathanrajagopalan 在官方 kotlinlang slack kotlinlang.slack.com/archives/C1CFAFJSK/… 上有一个松弛的讨论,他说“我认为它略有不同 - suspend fun main开始在主线程上执行,但如果你查看coroutineContext,它是EmptyCoroutineContext,这意味着Dispatchers.Default,并且从范围启动的任何协程都将在默认池上执行。” pl.kotl.in/HZUd3SohR从此github.com/Kotlin/kotlinx.coroutines官方文档推荐
猜你喜欢
  • 1970-01-01
  • 2017-06-28
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 2018-11-06
  • 2018-07-02
  • 1970-01-01
相关资源
最近更新 更多