我曾尝试阅读有关Kotlin协程的各种教程和页面,虽然我有点理解,但我仍然感觉没有真正掌握,也不觉得自己已经准备好使用协程编写异步非阻塞代码。我认为我需要的是一个图表或图片,来显示协程代码执行时确切发生的事情以及顺序。这段代码在线程级别上是如何运行的?
launch {
delay(1000)
println("World (${currentThread().name})")
}
println("Hello (${currentThread().name})")
sleep(1500)
我的理解是这样的。如果有更好的例子可以纠正我或者继续加深我的理解。
第0行:代码在主线程上启动
第1行:在一个新的线程上启动了一个新的协程(我想是从 forkjoin 池中)
第2行:挂起函数,协程暂停并将线程返回给线程池(因此是非阻塞状态)
第5行:在主线程上打印
第6行:阻塞主线程1.5秒
第3行:协程在某个线程上恢复执行(不确定是之前的挂起线程还是可能是另一个线程)。协程在该线程上打印并完成,然后再次将线程返回到线程池。
另一个问题是,如果我将整个代码用 runBlocking { ... }
包装起来,底层执行会如何改变?
runBlocking
干的不仅仅是这些,它为协程运行创建了一个环境。一旦你已经在协程环境中,它甚至不应该被使用。它不会在其协程完成之前结束只是这个函数的副作用。 - Marko Topolniklaunch
通常不能独立于创建它的主线程工作(在Android上的基本惯用法是让它在同一线程上工作),这也几乎正是使协程与线程如此不同的原因。你必须跳过这种认知上的障碍,接受现在在单个线程上存在并发。这是真正理解协程的关键。 - Marko Topolnik