You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 02:45:00