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

Kotlin协程async并行执行:如何实现无毫秒延迟触发所有函数?

Kotlin协程并行执行的时间同步问题

代码实现

以下是用Kotlin协程实现并行执行的代码:

suspend fun main() {
    sendDataAndAwaitAcknowledge()
}

suspend fun sendDataAndAwaitAcknowledge() = coroutineScope {
    awaitAll(
        async(Dispatchers.IO) { println(currTime("1")) },
        async(Dispatchers.IO) { println(currTime("2")) },
        async(Dispatchers.IO) { println(currTime("3")) },
        async(Dispatchers.IO) { println(currTime("4")) },
        async(Dispatchers.IO) { println(currTime("5")) },
        async(Dispatchers.IO) { println(currTime("6")) },
        async(Dispatchers.IO) { println(currTime("7")) },
        async(Dispatchers.IO) { println(currTime("8")) },
        async(Dispatchers.IO) { println(currTime("9")) },
        async(Dispatchers.IO) { println(currTime("10")) },
        async(Dispatchers.IO) { println(currTime("11")) },
        async(Dispatchers.IO) { println(currTime("12")) },
        async(Dispatchers.IO) { println(currTime("13")) },
        async(Dispatchers.IO) { println(currTime("14")) },
        async(Dispatchers.IO) { println(currTime("15")) }
    )
}

fun currTime(str: String): String {
    val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS")
    val now: LocalDateTime = LocalDateTime.now()
    return "count: $str  + time: ${dtf.format(now)}"
}

执行输出

运行后输出存在毫秒级差异:

count: 7  + time: 12:29:17.089
count: 1  + time: 12:29:17.089
count: 5  + time: 12:29:17.089
count: 8  + time: 12:29:17.089
count: 2  + time: 12:29:17.089
count: 11  + time: 12:29:17.089
count: 14  + time: 12:29:17.089
count: 10  + time: 12:29:17.090
count: 6  + time: 12:29:17.089
count: 12  + time: 12:29:17.090
count: 13  + time: 12:29:17.090
count: 15  + time: 12:29:17.089
count: 4  + time: 12:29:17.090
count: 3  + time: 12:29:17.090
count: 9  + time: 12:29:17.089

问题核心

期望所有协程触发时无毫秒延迟,即输出的时间完全一致,是否可行?

可行性分析

完全无毫秒延迟是不可行的,原因包括:

  • 协程调度存在开销:async创建协程、Dispatchers.IO将协程调度到线程池执行的过程,必然存在纳秒到微秒级的耗时,累积后会体现在毫秒级的时间差异上。
  • 线程执行有先后:线程池中的线程需要排队获取CPU时间片,无法做到绝对同时执行。
  • LocalDateTime.now()本身的调用也有微小开销,不同协程调用该方法的时间点必然存在先后。

替代方案

如果需要让所有输出时间保持一致,可以在创建协程之前提前获取基准时间,让所有协程复用这个时间,而非各自调用LocalDateTime.now():

修改后的代码(简洁版)

suspend fun main() {
    sendDataAndAwaitAcknowledge()
}

suspend fun sendDataAndAwaitAcknowledge() = coroutineScope {
    // 提前获取统一基准时间
    val baseTime = LocalDateTime.now()
    val dtf = DateTimeFormatter.ofPattern("HH:mm:ss.SSS")
    val formattedBaseTime = dtf.format(baseTime)
    
    awaitAll(
        async(Dispatchers.IO) { println("count: 1  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 2  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 3  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 4  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 5  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 6  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 7  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 8  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 9  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 10  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 11  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 12  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 13  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 14  + time: $formattedBaseTime") },
        async(Dispatchers.IO) { println("count: 15  + time: $formattedBaseTime") }
    )
}

保留函数的优化版

suspend fun main() {
    sendDataAndAwaitAcknowledge()
}

suspend fun sendDataAndAwaitAcknowledge() = coroutineScope {
    val baseTime = LocalDateTime.now()
    awaitAll(
        async(Dispatchers.IO) { println(currTime("1", baseTime)) },
        async(Dispatchers.IO) { println(currTime("2", baseTime)) },
        async(Dispatchers.IO) { println(currTime("3", baseTime)) },
        async(Dispatchers.IO) { println(currTime("4", baseTime)) },
        async(Dispatchers.IO) { println(currTime("5", baseTime)) },
        async(Dispatchers.IO) { println(currTime("6", baseTime)) },
        async(Dispatchers.IO) { println(currTime("7", baseTime)) },
        async(Dispatchers.IO) { println(currTime("8", baseTime)) },
        async(Dispatchers.IO) { println(currTime("9", baseTime)) },
        async(Dispatchers.IO) { println(currTime("10", baseTime)) },
        async(Dispatchers.IO) { println(currTime("11", baseTime)) },
        async(Dispatchers.IO) { println(currTime("12", baseTime)) },
        async(Dispatchers.IO) { println(currTime("13", baseTime)) },
        async(Dispatchers.IO) { println(currTime("14", baseTime)) },
        async(Dispatchers.IO) { println(currTime("15", baseTime)) }
    )
}

fun currTime(str: String, time: LocalDateTime): String {
    val dtf = DateTimeFormatter.ofPattern("HH:mm:ss.SSS")
    return "count: $str  + time: ${dtf.format(time)}"
}

通过这种方式,所有协程输出的时间都会和基准时间完全一致,达到视觉上的“无延迟”效果。


内容的提问来源于stack exchange,提问作者RaJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 23:32:04