Kotlin自定义runIOAsync协程函数任务未并行执行问题求助
问题原因
核心问题分为两点:
1. runIOAsync 函数实现错误,本身就是同步执行的
你在函数内使用了 coroutineScope 构造协程作用域,而 coroutineScope 的特性是必须等待内部所有子协程执行完成后才会返回。你在作用域内启动async之后,coroutineScope不会立刻返回Deferred,而是会一直阻塞到async包裹的IO任务执行完毕,才会把已经执行完成的Deferred返回给调用侧,等于这个封装函数从根上就没有异步执行的效果。
正确的异步封装不需要加coroutineScope,更规范的写法是给函数加上CoroutineScope接收者,避免结构化并发泄漏:
fun <T> CoroutineScope.runIOAsync(f: suspend () -> T): Deferred<T> = async(Dispatchers.IO) { f() }
修改后函数不会阻塞调用方,会立刻返回Deferred对象。
2. 调用侧逻辑强制串行
就算runIOAsync实现正确,你在repeat循环中每次启动任务后立刻调用.await(),也会导致每一轮循环都会等待当前任务执行完成才会进入下一轮,自然不会有并行效果。
正确的并行写法是先把所有任务的Deferred全部启动收集起来,再统一等待所有任务完成:
runBlocking { // 先启动所有异步任务,收集Deferred val tasks = List(5) { runIOAsync { println(it) println(Thread.currentThread()) Thread.sleep(3000) println("After sleep $it") } } // 统一等待所有任务完成 tasks.awaitAll() }
修改后运行就能看到5个任务几乎同时打印,3秒后同时输出After sleep的日志,达到并行执行的效果。
内容的提问来源于stack exchange,提问作者Chunsen
相关产品推荐
相关产品推荐

