为何GlobalScope.async性能优于coroutineScope.async?
Kotlin协程作用域与CPU密集型任务并行问题解答
问题描述
我正在开发一个小型Kotlin应用(基于Spring Boot),但对协程作用域理解不足,搞不懂异步协程返回结果的性能问题。
初始代码(串行执行,性能差)
@Component class GameRunner() : CommandLineRunner { override fun run(vararg args: String) = runBlocking { val players = listOf(Player(1), Player(2), Player(3), Player(4)) val results = mutableListOf<Results>() val measureTimeMillis = measureTimeMillis { val deferredResults = mutableListOf<Deferred<List<Results>>>() for (i in 0 until 250) { deferredResults.add(async { executeLadderRound(players.shuffled()) }) } results.addAll(deferredResults.awaitAll().flatten()) } // ... 展示结果 ... } // 纯阻塞式CPU密集型桌游模拟,无异步、等待或挂起操作 fun executeLadderRound(players: List<Player>): List<Results> }
这段代码仅占用约10%的CPU,耗时25秒,异步任务似乎是串行执行(移除async后耗时相同)。
修改后代码(并行执行,性能提升)
@Component class GameRunner() : CommandLineRunner { override fun run(vararg args: String) = runBlocking { val players = listOf(Player(1), Player(2), Player(3), Player(4)) val results = mutableListOf<Results>() val measureTimeMillis = measureTimeMillis { val deferredResults = mutableListOf<Deferred<List<Results>>>() for (i in 0 until 250) { deferredResults.add(GlobalScope.async { executeLadderRound(players.shuffled()) }) } results.addAll(deferredResults.awaitAll().flatten()) } // ... 展示结果 ... } // 纯阻塞式CPU密集型桌游模拟,无异步、等待或挂起操作 fun executeLadderRound(players: List<Player>): List<Results> }
性能大幅提升(耗时降至5秒)且CPU占用100%,符合预期。但疑问是:run作为主方法,默认作用域难道不是GlobalScope吗?
问题解答
1. runBlocking的作用域≠GlobalScope
runBlocking创建的是绑定当前线程的协程作用域,默认调度器不会启用线程池。而GlobalScope.async默认使用Dispatchers.Default调度器,该调度器会根据CPU核心数创建线程池,专门适配CPU密集型任务的并行执行。
2. 初始代码串行的核心原因
在runBlocking作用域中调用不带调度器参数的async时,async会继承当前作用域的调度器。由于executeLadderRound是纯阻塞方法,没有任何挂起点,协程无法让出当前线程,导致所有async任务必须串行执行在同一个线程上,CPU利用率自然极低,耗时和不用async完全一致。
3. 更优的实现方式(避免GlobalScope)
直接使用GlobalScope不推荐,因为它的生命周期不受控,容易引发内存泄漏。正确的做法是给async显式指定Dispatchers.Default调度器:
async(Dispatchers.Default) { executeLadderRound(players.shuffled()) }
这样既利用线程池并行执行CPU密集型任务,充分压榨CPU性能,又能保证协程作用域可控,避免GlobalScope带来的潜在问题。
内容的提问来源于stack exchange,提问作者darklurker
相关产品推荐
相关产品推荐

