我一直在试验Kotlin,并在kotlin协程上运行阻塞CPU任务。当诸如大型CPU密集型计算之类的事情阻塞时,我们实际上并没有暂停,而是需要在不同的线程上启动事物并使它们并行运行。
我设法使以下代码与async + Default调度程序一起按预期工作,但想知道它是否可以与withContext
一起使用,但没有。
fun cpuBlockingTasks() = runBlocking {
val time = measureTimeMillis {
val t1 = cpuTask(id = 1, blockTime = 500)
val t2 = cpuTask(id = 2, blockTime = 2000)
println("The answer is ${t1 + t2}")
}
println("Time taken: $time")
}
suspend fun cpuTask(id: Int, blockTime: Long): Int = withContext(Dispatchers.Default) {
println("work $id start ${getThreadName()}")
val res = doSomeCpuIntensiveTask(blockTime)
println("work $id end ${getThreadName()}")
res
}
fun doSomeCpuIntensiveTask(time: Long): Int {
Thread.sleep(time) // to mimick actual thread blocking / cpu work
return 1
}
此代码在> 2500毫秒内完成,并顺序在同一线程上运行。我原以为它会在一个线程中启动第一个协程,立即返回到调用方,并在另一个线程中启动第二个协程,但是那样就不起作用了。任何人都知道为什么会这样,以及如何在不使用调用程序函数中启动async
协程的情况下进行修复?
这是输出
work 1 start ForkJoinPool.commonPool-worker-5 @coroutine#1
work 1 end ForkJoinPool.commonPool-worker-5 @coroutine#1
work 2 start ForkJoinPool.commonPool-worker-5 @coroutine#1
work 2 end ForkJoinPool.commonPool-worker-5 @coroutine#1
The answer is 2
Time taken: 2523
答案 0 :(得分:1)
您没有在31 Aug 2019
和cpuTask 1
中创建新的协程。您只是在切换上下文。可以使用cpuTask 2
轻松修复:
async