我一直在试验Kotlin,并在kotlin协程上运行阻塞CPU任务。当程序阻塞时,比如大的cpu密集型计算,我们并不是真的挂起,而是需要在不同的线程上启动程序,让它们并行运行。
我设法让下面的代码在async + Default dispatcher下正常工作,但我想知道它是否能与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
}此代码在>2500ms内完成,并在同一线程上按顺序运行。我期望它在线程中启动第一个协程,立即返回到调用者,并在不同的线程上启动第二个协程,但并不是这样工作的。有人知道为什么会出现这种情况,以及如何在不在调用者函数中启动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发布于 2019-08-31 20:51:34
您没有在cpuTask 1和cpuTask 2中创建新的协程。您只是在切换上下文。可以使用async轻松修复此问题
fun cpuBlockingTasks() = runBlocking {
val time = measureTimeMillis {
val t1 = async { cpuTask(id = 1, blockTime = 500) }
val t2 = async { cpuTask(id = 2, blockTime = 2000) }
println("The answer is ${t1.await() + t2.await()}")
}
println("Time taken: $time") // Time taken: 2026
}https://stackoverflow.com/questions/57737998
复制相似问题