kotlin协程之coroutineScope函数使用详解
正文
public suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return suspendCoroutineUninterceptedOrReturn { uCont -> val coroutine = ScopeCoroutine(uCont.context, uCont, true) coroutine.startUndispatchedOrReturn(coroutine, block) } }
它是一个suspend
函数,创建一个新的协程作用域,并在该作用域内执行指定代码块,它并不启动协程。其存在的目的是进行符合结构化并发的并行分解(即,将长耗时任务拆分为并发的多个短耗时任务,并等待所有并发任务完成后再返回)。
coroutineScope
与runBlocking
的区别在于runBlocking
会阻塞当前线程,而coroutineScope
会挂起所在的协程直至其内部任务(包括子协程)执行完成,它不会阻塞所在的线程。
coroutineScope
是一个挂起函数,它被挂起后,会转而执行之前的子协程。
fun main() = runBlocking { launch { //launch① delay(1000) //挂起launch① println("test2") } println("test1") coroutineScope { //第一次挂起runBlocking,直至内部逻辑完成 launch { //launch② delay(2000) //挂起launch② println("test3") } delay(5000) //delay① //第二次挂起runBlocking println("test4") } println("test5") } //test1 //test2 //test3 //test4 //test5
代码分析
runBlocking
在main
线程创建并启动一个阻塞的协程;- 创建
launch①
子协程,由于创建协程是需要一些时间的,并且协程的创建是由特定的线程来完成,并非是main线程。所以在创建协程过程中会并行地执行后续代码。因此test1
被输出。 - 执行到
coroutineScope
函数时,把runBlocking
挂起,直到内部逻辑执行完成。 - 然后创建
launch②
协程,创建过程中执行执行后续代码:delay①
继续挂起runBlocking
5s(挂起函数中调用挂起函数)。 - 等到
launch①
创建完毕时,把它挂起1s。launch②
创建完毕时,把它挂起2s。 - 此时
runBlocking、launch①、launch②
都是被挂起状态。 - 等到1s后
launch①
恢复,输出test2
;2s后launch②
被恢复,输出test3
;5s后runBlocking
第二次挂起被恢复,输出test4
。 - 此时
coroutineScope
中的逻辑已经执行完成,恢复runBlocking
的第一次挂起,test5
被输出。
这比较难以理解,下面的案例稍微容易些:
fun main() = runBlocking { launch { println("test3") } println("test1") coroutineScope { //挂起runBlocking,直到内部逻辑完成 println("test2") delay(1000) //挂起runBlocking5s println("test4") } println("test5") //必须等待挂起函数coroutineScope执行完毕后才会被执行 } //test1 //test2 //test3 //test4 //test5
而如果把coroutineScope
函数改成delay
函数,会更加容易理解,因为它们都是挂起函数。
fun main() = runBlocking { launch { delay(1000) println("test2") } println("test1") delay(2000) //挂起runBlocking协程2s println("test3") } //test1 //test2 //test3
coroutineScope
经常用来把一个长耗时的任务拆分成多个子任务,使这些子任务并行执行
suspend fun showSomeData() = coroutineScope { val data1 = async { //子任务1 delay(2000) 100 } val data2 = async { //子任务2 delay(3000) 20 } withContext(Dispatchers.Default) { //合并结果并返回 delay(3000) val random = Random(10) data1.await() + data2.await() + random.nextInt(100) } }
coroutineScope
有如下语义:
- 并行执行内部任务
data1
、data2
、withContext
- 如果其它任务(
random
)抛出异常,data1
和data2
两个任务会被取消 - 如果
showSomeData()
被取消,内部的data1
、data2
、withContext
都会被取消 - 如果
data1
、data2
失败,withContext
被取消。
以上就是kotlin协程之coroutineScope函数使用详解的详细内容,更多关于kotlin协程coroutineScope函数的资料请关注脚本之家其它相关文章!
相关文章
Android Studio全局搜索快捷键(Ctrl+Shift+F)失效问题及解决
这篇文章主要介绍了Android Studio全局搜索快捷键(Ctrl+Shift+F)失效问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2023-01-01android bitmap compress(图片压缩)代码
android bitmap compress(图片压缩)代码,需要的朋友可以参考一下2013-06-06Android中使用PopupWindow 仿微信点赞和评论弹出
微信朋友圈的点赞和评论功能,有2个组成部分:左下角的“更多”按钮;点击该按钮后弹出的对话框。这篇文章主要介绍了Android中使用PopupWindow 仿微信点赞和评论弹出,需要的朋友可以参考下2017-04-04神奇的listView实现自动显示隐藏布局Android代码
这篇文章主要介绍了神奇的listView实现自动显示隐藏布局Android代码实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2016-09-09android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
在Android手机中,对于手机中的每个部件(cpu、led、gps、3g等等)运行时对应的能耗值都放在power_profile.xml文件中2014-02-02
最新评论