我已经尝试阅读了Kotlin协程的各种教程和页面,尽管它对我来说是有意义的,但我仍然没有感觉到它被点击了,我还没有准备好用协程编写异步非阻塞代码。我认为我缺少的是一张图表或图片,说明当一段协程代码执行时到底发生了什么,以及以什么顺序执行。这些代码是如何在线程级别运行的?
launch {
delay(1000)
println("World (${currentThread().name})")
}
println("Hello (${currentThread().name})")
sleep(1500)我的理解是这样的。我很高兴被纠正或给出一个不同的例子来加深我的理解。
Line0:代码在主线程上启动
Line1:在一个新线程上启动一个新的协程(我想是从forkjoin池)
Line2:挂起函数,以便协程挂起并将线程返回到线程池(因此是非阻塞的)
Line5:在主线程上打印
Line6:阻塞主线程1.5秒
Line3:协程恢复执行(不确定这里的哪个线程-与挂起前的线程相同,也可以是不同的线程?)。协程在该线程上打印并结束,因此再次将该线程返回到池。
我遇到的另一个问题是,如果我将整个代码包装在runBlocking { ... }中,底层执行会发生怎样的变化
发布于 2019-07-29 15:26:11
您的代码实际上不会做任何揭示协程的特殊性质的事情。它使两个线程同时执行它们的任务,就像它们在普通Java中所做的那样。
只有当您在已有的线程(例如,主线程)上启动协程时,它才会变得有趣。这是使用runBlocking块实现的事情之一:
runBlocking {
launch {
delay(1000)
println("Hello from the launched coroutine. My thread is "
+ Thread.currentThread().name)
}
println("Hello from the top-level coroutine. My thread is "
+ Thread.currentThread().name)
}这将打印出来
Hello from the top-level coroutine. My thread is main
Hello from the launched coroutine. My thread is mainrunBlocking在调用线程上运行一个事件循环,并将对它的引用传播到您在其中启动的所有协程。例如,delay(1000)将向此事件循环发送一个事件,并指示延迟一秒,然后它将挂起协程。这将允许主线程运行launch下面的其余代码。当时间过去时,事件循环将运行事件处理程序,该事件处理程序将依次恢复协程。
一个更有教育意义的例子是启动一个没有任何Dispatcher的协程。这消除了协程看起来像线程的假象,并揭示了它们的真正魔力:通过调用continuation.resume(),您可以使当前线程直接跳到挂起的协程的代码块的中间,所有这些都是使用普通的Java方法调用实现的。我建议学习this answer,在那里可以详细地解释这一点。如果您有兴趣更深入地解释普通的Java方法是如何做到这一点的,我建议您在YouTube上观看罗曼·伊利扎罗夫·explaining this。
发布于 2019-07-29 09:33:49
这里有另一个例子:https://kotlinlang.org/docs/reference/coroutines/basics.html#your-first-coroutine
fun main() {
GlobalScope.launch { // launch a new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay
}
println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}上面的代码打印如下:
Hello,
World!正如您所看到的,尽管代码看起来是同步的,但执行是异步的。这就是协程的全部想法。
https://stackoverflow.com/questions/57243903
复制相似问题