14 | 如何启动协程?
协程调试
协程 VM 参数
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了协程的启动方式和调试技巧。作者首先强调了掌握协程调试技巧的重要性,介绍了通过设置VM参数和使用IDE的断点调试功能两种方式进行协程调试。在设置VM参数方面,作者指出可以通过将VM参数设置成“-Dkotlinx.coroutines.debug”来在log中打印协程相关信息。在断点调试方面,作者提到了升级IDE版本、确保Kotlin编译器插件版本号大于1.4以及为协程代码打断点等注意事项,并展示了相关操作步骤和调试窗口的信息。 接着,作者介绍了启动协程的三种方式:runBlocking、launch和async。runBlocking会阻塞当前线程的执行,适用于连接线程与协程,但不推荐在生产环境中使用。launch是典型的“Fire-and-forget”场景,不会阻塞当前程序的执行流程,但无法直接获取协程的执行结果。而async则结合了launch和runBlocking的优点,不会阻塞当前的执行流程,同时可以直接获取协程的执行结果。 文章通过实例代码和详细解释,帮助读者理解了协程的启动方式和特点,以及协程调试的方法,为读者提供了实用的技术指导。总体而言,本文内容详细、实用,对于想要学习协程的读者来说具有很高的参考价值。
《朱涛 · Kotlin 编程第一课》,新⼈⾸单¥59
全部留言(31)
- 最新
- 精选
- Allen后面思考题的执行结果为: In async .... In async after delay.... 我的思考是 async 类比钓鱼,鱼钩已经扔出去了,钓鱼的这个动作已经开始了,只是我并没有拉杆。
作者回复: 这个比喻很棒!
2022-02-14528 - Geek_Adrasync != lazy await只是等待执行完,并不是触发执行
作者回复: 总结很到位!
2022-02-20210 - 面无表情的生鱼片老师用“射箭”和“钓鱼”来做比喻真是让人想忘都忘不掉! 不过我有一点关于思考题的反思: 虽然说 `async{}` 是不阻塞的,但是后续 `deferred.await()` 会阻塞。 严格意义上是否可以认为 `async{}` + `deferred.await()` 是阻塞的。 单用 `async()` 而不调用 `deferred.await()` 的情况应该使用 `launch{}`,在这种情况下老师列的表格中标注 `async{}` 是不阻塞是否意义不大?
作者回复: 你的理解很到位。async{}对比launch{}的不同还是在于返回值,至于`async{}` 是不阻塞其实是对比runBlocking的。
2022-02-1548 - 魏全运思考题: In async:main In.async after delay! 请问这里是有什么让人容易忽略的细节吗?
作者回复: 有些同学会认为deferred.await()如果不调用的话,async当中的代码就不会执行。
2022-02-1458 - Gavin对于GlobalScope有疑问,阅读了源码注释,也不是很清楚为什么GlobalScope不建议用,能帮忙解释下吗
作者回复: GlobalScope最大的劣势,就是不具备“结构化并发”的能力。
2022-02-2437 - 遥远的救世主我用 Android Studio Chipmunk | 2021.2.1 Patch 1,设置VM 参数后调试协程名还是不打印,debug也没有协程那一项,Google 开发的工具不给力啊
作者回复: 你得试试 JetBrains 的 IDE,Android Studio 的版本是落后与 JetBrains 的。
2022-05-274 - neo你好,既然launch和runBlocking都不建议在生产环境中使用,只能使用async。 但是async也是需要CoroutineScope对象,但是GlobalScope也不建议使用,那我们在生产环境中应该使用怎样的方式来开启协程呢
作者回复: 只是runBlocking不建议在生产环境使用。如果你是Android开发,官方为你提供了LifecycleScope、ViewModelScope。如果是其他端,则可以自己创建CoroutineScope。
2022-04-2233 - PoPlus思考题:async 函数就像 launch 函数会异步执行,所以会输出结果。 只是 async 函数有个对应的 await 函数可以接收值,这个接收过程是阻塞式的。
作者回复: 没错~
2022-02-222 - ACE_Killer09fun main() { GlobalScope.launch { // 1 println("Coroutine started!") // 2 delay(1000L) // 3 println("Hello World!") // 4 } println("After launch!") // 5 Thread.sleep(2000L) // 6 println("Process end!") // 7 } /* 输出结果: After launch! Coroutine started! Hello World! Process end! */ 执行顺序为啥不是 1、5、6、2、3、4、7? 5 比 2 先执行是不是说明启动协程需要时间?
作者回复: 应该是: 1、5、6、2、3、4、7,你没错。 5 比 2 先执行是不是说明启动协程需要时间?这其实是由一些其他协程参数决定的,你可以参考17讲的内容。
2022-02-2122 - syz@Test fun main2() = runBlocking { val deferred: Deferred<String> = async { println("In async:${Thread.currentThread().name}") delay(1000L) // 模拟耗时操作 println("In async after delay!") println(this@runBlocking.isActive) return@async "Task completed!" } } In async:Test worker @coroutine#2 In async after delay! true 没有delay也会显示,runBlocking执行完还是active,也不会影响内部async的执行
作者回复: 是的,这位同学很细心。
2022-04-151