如何在与 Kotlin 协程并行运行两个函数后运行第三个函数

问题描述 投票:0回答:1

我正在尝试并行运行 2 个函数,之后我想使用前 2 个函数的结果启动第三个函数。

我搜索了 Google 和 StackOverflow,并尝试了下面的代码。
但是 func2() 是在 func1() 完成之后才开始的,而不是并行的。
日志如下。
开始 func1 -> 结束 func1 -> 开始 func2 -> 结束 func2 -> 10 + 20 = 30

如何并行运行 2 个函数?

    val TAG = "TagMainActivity"
    val dispatcher = Executors.newSingleThreadExecutor().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())
        }
    }

    suspend fun func1(): Int {
        Log.d(TAG, "Start func1")
        Thread.sleep(3000)
        Log.d(TAG, "End func1")
        return 10
    }

    suspend fun func2(): Int {
        Log.d(TAG, "Start func2")
        Thread.sleep(3000)
        Log.d(TAG, "End func2")
        return 20
    }

    suspend fun func3(bmp1: Int, bmp2: Int) {
        Log.d(TAG, "$bmp1 + $bmp2 = ${bmp1 + bmp2}")
    }
kotlin coroutine
1个回答
0
投票

您使用 async 并行运行 func1()func2(),在它们都完成后,您调用 func3() 对结果求和。然而,在挂起函数中使用 Thread.sleep() 有一个小问题 — 这是一个阻塞操作,应该替换为像 delay() 这样的非阻塞挂起函数。

Thread.sleep() 会阻塞线程并可能导致性能问题,尤其是在协程中。由于您已经在使用协程,因此您应该使用delay()来挂起协程而不阻塞线程。

val TAG = "TagMainActivity" val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Launch the coroutine in a custom dispatcher lifecycleScope.launch(dispatcher) { val job1 = async { func1() } val job2 = async { func2() } // Wait for both jobs to finish and call func3 func3(job1.await(), job2.await()) } } // Non-blocking version of func1 using delay instead of Thread.sleep suspend fun func1(): Int { Log.d(TAG, "Start func1") delay(3000) // Non-blocking delay Log.d(TAG, "End func1") return 10 } // Non-blocking version of func2 using delay instead of Thread.sleep suspend fun func2(): Int { Log.d(TAG, "Start func2") delay(3000) // Non-blocking delay Log.d(TAG, "End func2") return 20 } // Function to log the results after both func1 and func2 are done suspend fun func3(bmp1: Int, bmp2: Int) { Log.d(TAG, "$bmp1 + $bmp2 = ${bmp1 + bmp2}") } override fun onDestroy() { super.onDestroy() dispatcher.close() // Clean up the dispatcher to avoid memory leaks }

用delay()替换Thread.sleep():由于Thread.sleep()是阻塞调用,它可以冻结整个线程。 delay() 挂起协程而不阻塞线程,这对于协程来说更合适。

您应该在onDestroy()中调用dispatcher.close()来正确清理SingleThreadExecutor以避免内存泄漏。如果您使用的是标准调度程序(例如 Dispatchers.IO 或 Dispatchers.Default),则可以跳过此步骤。

© www.soinside.com 2019 - 2024. All rights reserved.