Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 为什么这些协同程序不能提供预期的输出?_Kotlin_Kotlinx.coroutines - Fatal编程技术网

Kotlin 为什么这些协同程序不能提供预期的输出?

Kotlin 为什么这些协同程序不能提供预期的输出?,kotlin,kotlinx.coroutines,Kotlin,Kotlinx.coroutines,我试图了解科特林的合作项目,但我遇到了一些障碍。在以下示例中,我预计会发生以下情况: 打印0 安装作业1 安装作业2 印刷品3 运行作业1 等待1.2秒 印刷品1 印刷品4 运行作业2 等待1秒钟 印刷品2 印刷品5 印刷品6 但它打印的是: 0 3 2 1 4 5 六, 我真的不明白为什么会这样。我基本上不明白job2的输出怎么会出现在4之前。我很困惑 println("0") runBlocking { val job = GlobalScope.launch {

我试图了解科特林的合作项目,但我遇到了一些障碍。在以下示例中,我预计会发生以下情况:

  • 打印0
  • 安装作业1
  • 安装作业2
  • 印刷品3
  • 运行作业1
  • 等待1.2秒
  • 印刷品1
  • 印刷品4
  • 运行作业2
  • 等待1秒钟
  • 印刷品2
  • 印刷品5
  • 印刷品6
但它打印的是:

0
3
2
1
4
5
六,

我真的不明白为什么会这样。我基本上不明白
job2
的输出怎么会出现在
4
之前。我很困惑

println("0")
runBlocking {
    val job = GlobalScope.launch {
        // launch new coroutine and keep a reference to its Job
        delay(1200L)
        println("1")
    }
    val job2 = GlobalScope.launch {
        // launch new coroutine and keep a reference to its Job
        delay(1000L)
        println("2")
    }

    println("3")
    job.join() // wait until child coroutine completes
    println("4")
    job2.join() // wait until child coroutine
    println("5")
}
println("6")
阅读下列文件:

默认情况下,将立即计划执行协同路由。其他启动选项可通过启动参数指定。有关详细信息,请参阅CoroutineStart。可选的启动参数可以设置为CoroutineStart.LAZY以延迟启动协同程序。在这种情况下,将在新状态下创建协同程序作业。它可以用start函数显式启动,并在第一次调用join时隐式启动

因此,您的协同程序在
launch
命令之后立即启动。这应该解释执行命令的顺序。异步协程中的
延迟
会在主线程执行下一个语句时立即执行<代码>3在
2
之前在
1
之前。然后等待第一个作业完成(打印
1
),然后再从主线程打印
4

如果希望代码按预期执行,可以将
start=CoroutineStart.LAZY
参数添加到
launch
中,如下所示:

println("0")
runBlocking {
    val job = GlobalScope.launch(start = CoroutineStart.LAZY) {
        // launch new coroutine and keep a reference to its Job
        delay(1200L)
        println("1")
    }
    val job2 = GlobalScope.launch(start = CoroutineStart.LAZY) {
        // launch new coroutine and keep a reference to its Job
        delay(1000L)
        println("2")
    }

    println("3")
    job.join() // wait until child coroutine completes
    println("4")
    job2.join() // wait until child coroutine
    println("5")
}
println("6")
情况就是这样:

  • 打印0
  • 输入,它将阻止当前线程,直到阻止完成
  • 设置和1;作业立即开始执行,并被延迟语句暂停1200毫秒
  • 设置并启动job2;作业立即开始执行,并通过delay语句暂停1000米
  • 打印3
  • 等待(执行挂起),直到作业1完成(
    job.join()
  • 1000毫秒后,job2打印2并完成
  • 1200毫秒后,job1打印1并完成
  • 打印4(因为作业1已完成)
  • 等待(执行挂起),直到job2完成(
    job2.join()
    )。这会立即返回,因为job2已经完成
  • 打印5
  • 打印6,在-block完成并且开始的线程继续之后

  • 您可以阅读本文以更好地了解挂起函数。帮助我理解协同程序的是以下视频:

    join
    不启动协同程序,它只等待完成
    launch
    已经启动了它。
    launch
    立即启动co例程,这样您就可以打印3,然后
    job2
    首先完成(当您等待
    job
    时),如果您使用
    GlobalScope.launch(start=CoroutineStart.LAZY){…
    将启动延迟到
    start()
    ,您将得到该输出,
    wait()
    join()