我尝试阅读有关Kotlin协程的各种教程和页面,尽管这对我来说很有意义,但我仍然觉得它没有被点击,并且我不准备跳动使用协程编写异步非阻塞代码。我认为我所缺少的是当一段协程代码执行时发生的确切情况和顺序的图表。该代码如何在线程级别运行?
launch {
delay(1000)
println("World (${currentThread().name})")
}
println("Hello (${currentThread().name})")
sleep(1500)
我的理解是这样。我很高兴得到改正或举一个不同的例子来加深我的理解。
第0行:代码从主线程开始
第1行:在新线程上启动新的协程(我想是从forkjoin池中获得的)
Line2:挂起函数,以便协程挂起并将线程返回到线程池(因此是非阻塞的)
第5行:在主线程上打印
第6行:阻塞主线程1.5秒
第3行:协程在其上继续执行(不确定此处的哪个线程-与暂停前的线程相同还是可以是其他线程?)。协程程序在该线程上打印并完成,因此将线程再次返回到池中。
我还有一个问题是,如果我将整个代码包装在runBlocking { ... }
周围,低级执行将会如何改变
答案 0 :(得分:0)
这里是此处提到的另一个示例: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!
如您所见,尽管代码看起来是同步的,但执行是异步的。那就是协程的全部想法。
答案 1 :(得分:0)
您的代码实际上没有做任何能揭示协程特殊性质的事情。它使两个线程可以同时执行其操作,就像在纯Java中一样。
只有在您已经在同一线程上启动协程时(例如,主线程),它才会变得有趣。这是使用runBlocking
块可以实现的目标之一:
runBlocking {
launch {
println("Hello from launched coroutine. My thread is "
+ Thread.currentThread().name)
}
delay(1000)
println("Hello from the top-level coroutine. My thread is "
+ Thread.currentThread().name)
}
这将打印
Hello from launched coroutine. My thread is main
Hello from the top-level coroutine. My thread is main
一个更具教育意义的示例是在没有任何Dispatcher
的情况下启动协程。这消除了看起来像线程的协程的“幻觉”,并揭示了真正的魔力:通过调用continuation.resume()
,您可以使当前线程跳入暂停的协程代码块的中间,所有这些操作均使用纯Java方法进行电话。我建议研究this answer,在此进行详细说明。