bennyhuo / Bennyhuo

bennyhuo.vercel.app
9 stars 3 forks source link

破解 Kotlin 协程(2) - 协程启动篇 | Bennyhuo #16

Open bennyhuo opened 5 years ago

bennyhuo commented 5 years ago

https://www.bennyhuo.com/2019/04/08/coroutines-start-mode/

破解 Kotlin 协程 - 入门篇现在你已经知道协程大概是怎么回事了,也应该想要自己尝试一把了吧。本文将为大家详细介绍协程的几种启动模式之间的不同,当然,我不打算现在就开始深入源码剖析原理,大家只需要记住这些规则就能很好的使用协程了。

vincentlauvlwj commented 5 years ago

讲得真好~~

小小杠一下,SimpleDateFormat 是线程不安全的,JVM 的协程根据不同的调度器可能运行在多线程的环境,所以这个 log() 函数可能有问题

bennyhuo commented 5 years ago

@vincentlauvlwj 嗯,好吧,这个挑的没毛病。不过说真的 DateFormat 的设计真的是有问题,这么个东西居然是不纯的。。

vincentlauvlwj commented 5 years ago

你好,我非常喜欢 Kotlin,也关注你的 Kotlin 教程很久了。这是我使用 Kotlin 开发的一个 ORM 框架,它提供了强类型而且灵活的 SQL DSL 和方便的序列 API,如果觉得不错的话可以麻烦点个 star 吗?GitHub 地址:https://github.com/vincentlauvlwj/Ktorm

十分感谢!!

bennyhuo commented 5 years ago

@vincentlauvlwj 你好,我非常喜欢 Kotlin,也关注你的 Kotlin 教程很久了。这是我使用 Kotlin 开发的一个 ORM 框架,它提供了强类型而且灵活的 SQL DSL 和方便的序列 API,如果觉得不错的话可以麻烦点个 star 吗?GitHub 地址:https://github.com/vincentlauvlwj/Ktorm

十分感谢!!

看上去很用心!回头我邮件联系你一下,如果有机会的话,写一篇文章介绍下你的框架,欢迎投稿到微信公众号 Kotlin~

dokinkon commented 5 years ago

最棒的中文coroutine教學!

bennyhuo commented 5 years ago

@dokinkon 最棒的中文coroutine教學!

感谢肯定!

whataa commented 5 years ago

你好,感谢你的教程,我这里的UNDISPATCHED 打印和文章的不太一样,可以解答下吗?

[main] 1
[main] 2
[main] 4
[DefaultDispatcher-worker-1] 3
[main] 5
bennyhuo commented 5 years ago

@whataa 你好,感谢你的教程,我这里的UNDISPATCHED 打印和文章的不太一样,可以解答下吗?

[main] 1
[main] 2
[main] 4
[DefaultDispatcher-worker-1] 3
[main] 5

join 本来就有两个路径, 如果协程已经执行完就会立即返回。

Mr-Luowan commented 4 years ago

大佬想问下 UNDISPATCHED 那个案例为什么5会在worker输出 而不是main

bennyhuo commented 4 years ago

@Mr-Luowan 大佬想问下 UNDISPATCHED 那个案例为什么5会在worker输出 而不是main

取决于 join 是否真正挂起,如果挂起,那么 join 处恢复执行时如果所在协程有调度器,那么 5 在调度器对应的线程上执行,如果没有调度器,那么就在 join 恢复执行的线程执行。如果 join 没有挂起,那么 5 在 join 调用所在的线程执行。


再补充一下,例子里面有个 delay 所以一定会挂起。至于大家的结果为什么跟文章不同,主要原因在于外层代码的不同。如果在示例代码外层包的协程包含调度器,那么 5 会在对应的调度器里面执行,如果没有调度器,那么 5 会在 join 挂起后恢复时所在的线程执行。

BreakZero commented 4 years ago

您好, 在 LAZY 那块,直接使用job.start(),经常不打印结果 2 ,感觉是JVM shutdown 比输出还早。所以是不是main 函数suspend 修饰是无效的(因为start方法也不是suspend的),所以导致main函数其实没有Continuation, 所以启动的协程没有上下文,因此JVM 在协程completed 之前shutdown了。如果将main函数加上runBlocking块,结果就能正常,因为在外围加了Continuation,从而使得子协程完成后JVM才shutdown。这样的理解是不是正确的? 备注: kotlin 版本 1.3.61

BreakZero commented 4 years ago

@whataa 你好,感谢你的教程,我这里的UNDISPATCHED 打印和文章的不太一样,可以解答下吗?

[main] 1
[main] 2
[main] 4
[DefaultDispatcher-worker-1] 3
[main] 5

是不是main 函数用的是runBlocking 块包括了呀?如果跟作者一样用suspend来修饰main函数结果是一样的

bennyhuo commented 4 years ago

@whataa 你好,感谢你的教程,我这里的UNDISPATCHED 打印和文章的不太一样,可以解答下吗?

[main] 1
[main] 2
[main] 4
[DefaultDispatcher-worker-1] 3
[main] 5

是不是main 函数用的是runBlocking 块包括了呀?如果跟作者一样用suspend来修饰main函数结果是一样的

这个正常的,我确实没有交代外层的协程代码,如果你外层的协程有调度器,5 就会在对应的调度器调度后的线程上执行。

CoenQian commented 3 years ago

@whataa 你好,感谢你的教程,我这里的UNDISPATCHED 打印和文章的不太一样,可以解答下吗?

[main] 1
[main] 2
[main] 4
[DefaultDispatcher-worker-1] 3
[main] 5

如果 CoroutineContext 里有调度器,续体会在调度器里执行 resume,如果没有就是当前线程里 resume

XiCoder commented 1 year ago

huo老师,这个ATOMIC模式的描述有一点绕,可不可以理解为ATOMIC模式保证了即使协程被取消了,协程体内挂起点之前的方法一定会被执行

bennyhuo commented 1 year ago

没错