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
相关产品推荐
相关产品推荐

