Kotlin协程async未并行执行任务问题求助
Kotlin协程async未并行执行的问题修复
我在测试中使用Kotlin协程时,发现async代码块会在上一个执行完成后才启动下一个,不符合预期的并行逻辑。测试代码如下:
@Test fun `xyz`() { runBlocking { val x = async { x() } val y = async { y() } val z = async { z() } println("x, y, z -> ${x.await()} , ${y.await()}, ${z.await()} ") } } fun x() = "x".also { repeat(1000) { println("waiting for network response.") } println("returning x") } fun y() = "y".also { println("returning y") } fun z() = "z".also { println("returning z") }
运行后returning y和returning z要等x()执行完成后才打印,请问如何修改才能让这三个调用并发执行?(注:测试代码也可直接在main函数中运行)
问题原因
核心问题出在协程调度器的选择:
runBlocking默认使用调用它的线程作为协程上下文(单线程环境),且你的x()、y()、z()都是普通阻塞同步函数,没有任何挂起操作(比如delay())。- 在单线程上下文里,协程无法自动切换执行权,必须等当前协程的阻塞代码完全执行完毕,才会轮到下一个协程运行,最终导致
async块串行执行。
解决方案
根据你的实际场景,有两种可行的修改方式:
方式1:给async指定多线程调度器(适合阻塞任务)
给每个async块指定Dispatchers.IO或Dispatchers.Default调度器,让阻塞任务在不同线程上并行执行:
@Test fun `xyz`() { runBlocking { val x = async(Dispatchers.IO) { // 指定多线程调度器 x() } val y = async(Dispatchers.IO) { y() } val z = async(Dispatchers.IO) { z() } println("x, y, z -> ${x.await()} , ${y.await()}, ${z.await()} ") } }
方式2:将函数改为挂起函数(推荐非阻塞场景)
如果你的实际业务是真正的非阻塞IO(比如使用Kotlinx Coroutines生态的网络库),可以把函数改成挂起函数,用delay()模拟挂起操作,这样即使在单线程上下文里,协程也能自动切换执行:
@Test fun `xyz`() { runBlocking { val x = async { x() } val y = async { y() } val z = async { z() } println("x, y, z -> ${x.await()} , ${y.await()}, ${z.await()} ") } } suspend fun x(): String = "x".also { repeat(1000) { println("waiting for network response.") delay(1) // 模拟挂起,让出执行权给其他协程 } println("returning x") } suspend fun y(): String = "y".also { println("returning y") } suspend fun z(): String = "z".also { println("returning z") }
内容的提问来源于stack exchange,提问作者Makruzz
相关产品推荐
相关产品推荐

