难以理解Kotlin协程输出

uqdfh47h  于 2023-03-03  发布在  Kotlin
关注(0)|答案(2)|浏览(173)
fun main() {
    println("Start of program")
    GlobalScope.launch{

        println("Starting coroutine")
        val result = someOperation()
        println("Coroutine Running thread is: ${Thread.currentThread().name}")
        println("Coroutine completed with result: $result")
        println("End of the coroutine function")

    }
    println("End of program")
}

suspend fun someOperation(): String { //This is a coroutine now (Due to suspend modifier).
    delay(3000) // long-running operation
    return "Operation performed successfully"
}

有人能解释一下为什么我的输出是这个吗?

Start of program
End of program

而预期产出是:

Start of program
Starting coroutine
Coroutine Running thread is: DefaultDispatcher-worker-1
Coroutine completed with result: Operation performed successfully
End of the coroutine function
End of program

如果协程应该在后台线程上运行,为什么在上面的例子中协程甚至没有被调用呢?
据我所知,主函数应该首先被触发,它应该产生协程(最终线程),至少在完成主函数之后,程序应该在退出之前给予协程完成的机会。

**P.S:**我在协程和异步编程方面有很大的困难。如果有人有同样的好资源,请分享它将会很有帮助。

owfi6suc

owfi6suc1#

启动协程会将其排队以开始异步运行。当它开始运行时,主函数会同步继续。当它返回时,应用已完成,因此它会终止。如果您希望应用保持打开状态以等待协程完成,您需要在launch返回的作业上调用join()。要在main中执行此操作,您需要将main标记为suspend函数,或者将其所有代码包含在runBlocking { }中,以便在其中调用suspend函数。
或者,如果您使用runBlocking,则可以直接启动子协程而不使用GlobslScope,这样就不必在其上调用join()runBlocking会自动等待其所有子协程完成。

snz8szmq

snz8szmq2#

如果您查看GlobalScope的文档,它明确指出:
在GlobalScope中启动的活动协程并不保持进程的活动状态。它们就像守护进程线程。
但这并不是GlobalScope所特有的。协程通常不会让进程保持活动状态。线程可以。协程是围绕结构化并发的概念设计的,其中任务由较小的子任务组成,并等待它们完成。如果我们启动了一个协程,但我们没有以任何方式观察它,它就不是一个更大任务的一部分,等等。那就好像我们不再需要这个协程了,这类似于分配一个对象,但不存储对它的引用。
使用协程的常见模式是在main()中调用runBlocking(),并将其作为“根”协程,它是应用程序中运行的所有/大多数协程的父级。这样我们可以很容易地确保不会泄漏任何后台任务,我们可以取消整个应用程序的所有任务,等等。

相关问题