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

如何用Kotlin协程并行执行两函数后再运行第三个函数?

如何实现Kotlin协程并行执行两个函数

你的代码无法实现并行的核心原因是:使用了Executors.newSingleThreadExecutor().asCoroutineDispatcher()单线程调度器——所有协程任务都会在同一个线程里排队执行,async启动的func1和func2自然只能串行运行。

核心修复:更换为多线程调度器

要让协程并行,必须使用支持多线程的调度器,以下是两种常用方案:

1. 使用内置Dispatchers.Default

Dispatchers.Default是Kotlin协程提供的默认多线程调度器,线程数通常等于设备CPU核心数,适合CPU密集型任务。

修改后的代码:

val TAG = "TagMainActivity"

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    lifecycleScope.launch(Dispatchers.Default) {
        val job1 = async { func1() }
        val job2 = async { func2() }
        func3(job1.await(), job2.await())
    }
}

suspend fun func1(): Int {
    Log.d(TAG, "Start func1, thread: ${Thread.currentThread().name}")
    delay(3000) // 替换Thread.sleep为协程非阻塞挂起函数
    Log.d(TAG, "End func1")
    return 10
}

suspend fun func2(): Int {
    Log.d(TAG, "Start func2, thread: ${Thread.currentThread().name}")
    delay(3000)
    Log.d(TAG, "End func2")
    return 20
}

suspend fun func3(bmp1: Int, bmp2: Int) {
    Log.d(TAG, "$bmp1 + $bmp2 = ${bmp1 + bmp2}")
}

2. 自定义多线程线程池

如果需要精准控制线程数量(比如固定2个线程),可以用Executors.newFixedThreadPool创建自定义调度器:

val TAG = "TagMainActivity"
// 自定义2线程的调度器
val dispatcher = Executors.newFixedThreadPool(2).asCoroutineDispatcher()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    lifecycleScope.launch(dispatcher) {
        val job1 = async { func1() }
        val job2 = async { func2() }
        func3(job1.await(), job2.await())
    }

    // 注意:在Activity销毁时关闭调度器,避免内存泄漏
    lifecycle.addObserver(object : DefaultLifecycleObserver {
        override fun onDestroy(owner: LifecycleOwner) {
            dispatcher.close()
        }
    })
}

// func1、func2、func3代码同上

额外优化:用delay替代Thread.sleep

Thread.sleep是阻塞线程的操作,会占用线程资源直到休眠结束;而delay是协程的非阻塞挂起函数,会暂时释放线程给其他协程使用,更符合协程的高效特性。如果你的实际任务是IO密集型操作,还可以改用Dispatchers.IO调度器。

修改后日志输出顺序会变为:
Start func1 → Start func2 → 3秒后同时输出End func1和End func2 → 10 + 20 = 30,真正实现并行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:35:09