【Kotlin 协程】协程启动 ② ( 多协程控制 | launch 协程执行顺序控制 | Job#join() 函数 | async 协程执行顺序控制 | Deferred#await() 函数 )
文章目录
- 一、launch 协程执行顺序控制
- 二、async 协程执行顺序控制
- 三、完整代码
源码地址 : https://download.csdn.net/download/han1202012/87183425
一、launch 协程执行顺序控制
如果需要通过 launch 协程构建器 启动多个协程 , 后面的协程需要等待前面的协程执行完毕 , 在启动靠后的协程 , 实现方案如下 :
调用 Job#join() 函数 , 可以挂起协程 , 等待 launch 中协程体内的任务执行完毕 , 再执行后面的协程任务 ;
代码示例 : 下面的代码中 , 先执行 launchJob 协程 , 调用 launchJob.join() 函数会挂起协程 , 该 launchJob 协程任务执行完毕后 , 才会执行后面的 launch 协程任务 ;
runBlocking {// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程val launchJob = launch {// 调用该挂起函数延迟 100 msdelay(100)Log.i(TAG, "launchJob 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务launchJob.join()val launchJob1 = launch {// 调用该挂起函数延迟 100 msdelay(100)Log.i(TAG, "launchJob1 执行完毕")}
}
Job#join() 函数原型如下 : 该函数是挂起函数 , 不会阻塞主线程 ;
/*** 挂起协程,直到此作业完成。此调用正常恢复(没有异常)* 当作业因任何原因完成且调用协程的[job]仍为[active][isActive]时。* 这个函数也[启动][Job。如果[Job]仍然处于_new_状态,则启动]相应的协程。** 注意,只有当所有子任务都完成时,作业才算完成。** 这个挂起函数是可取消的,并且**总是**检查是否取消了调用协程的Job。* 如果调用协程的[Job]被取消或完成* 函数被调用,或当它被挂起时,此函数* 把[CancellationException]。** 特别是,它意味着父协程在子协程上调用' join '时抛出* [CancellationException]如果子进程失败,因为子进程的失败会默认取消父进程,* 除非子进程是从[supervisor orscope]内部启动的。** 此函数可用于带有[onJoin]子句的[select]调用。* 使用[isCompleted]检查该作业是否已完成,无需等待。** 有一个[cancelAndJoin]函数,它结合了[cancel]和' join '的调用。*/
public suspend fun join()
源码地址 : https://download.csdn.net/download/han1202012/87183425
完整代码示例 :
package kim.hsl.coroutineimport android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlockingclass MainActivity : AppCompatActivity(){val TAG = "MainActivity"override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)runBlocking {// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程val launchJob = launch {// 调用该挂起函数延迟 100 msdelay(100)Log.i(TAG, "launchJob 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务launchJob.join()val launchJob1 = launch {// 调用该挂起函数延迟 100 msdelay(50)Log.i(TAG, "launchJob1 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务launchJob1.join()val launchJob2 = launch {// 调用该挂起函数延迟 100 msdelay(10)Log.i(TAG, "launchJob2 执行完毕")}}}
}
二、async 协程执行顺序控制
如果需要通过 async 协程构建器 启动多个协程 , 后面的协程需要等待前面的协程执行完毕 , 在启动靠后的协程 , 实现方案如下 :
调用 Deferred#await() 函数 , 可以挂起协程 , 等待 async 中协程体内的任务执行完毕 , 再执行后面的协程任务 ;
代码示例 : 下面的代码中 , 先执行 asyncDeferred 协程 , 调用 asyncDeferred.await() 函数会挂起协程 , 该 asyncDeferred 协程任务执行完毕后 , 才会执行后面的 async 协程任务 ;
runBlocking {// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程val asyncDeferred = async {// 调用该挂起函数延迟 100 msdelay(100)Log.i(TAG, "asyncDeferred 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务asyncDeferred.await()val asyncDeferred1 = async {// 调用该挂起函数延迟 100 msdelay(50)Log.i(TAG, "asyncDeferred1 执行完毕")}
}
Deferred#await() 函数原型如下 : 该函数是挂起函数 , 不会阻塞主线程 ;
/*** 在不阻塞线程的情况下等待该值的完成,并在延迟的计算完成时恢复,* 返回结果值,如果取消了延迟,则抛出相应的异常。** 这个暂停功能是可以取消的。* 如果当前协程的[Job]在此挂起函数等待时被取消或完成,则此函数* 立即恢复[CancellationException]。* 有**立即取消的保证**。如果在此函数被取消时作业被取消* 挂起后,它将无法成功恢复。有关底层细节,请参阅[suspendCancellableCoroutine]文档。** 这个函数可以在[select]调用和[onAwait]子句中使用。* 使用[isCompleted]检查这个延迟值是否已经完成,无需等待。*/
public suspend fun await(): T
源码地址 : https://download.csdn.net/download/han1202012/87183425
完整代码示例 :
package kim.hsl.coroutineimport android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlockingclass MainActivity : AppCompatActivity(){val TAG = "MainActivity"override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)runBlocking {// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程val asyncDeferred = async {// 调用该挂起函数延迟 100 msdelay(100)Log.i(TAG, "asyncDeferred 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务asyncDeferred.await()val asyncDeferred1 = async {// 调用该挂起函数延迟 100 msdelay(50)Log.i(TAG, "asyncDeferred1 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务asyncDeferred1.await()val asyncDeferred2 = async {// 调用该挂起函数延迟 100 msdelay(10)Log.i(TAG, "asyncDeferred2 执行完毕")}}}
}
执行结果 :
三、完整代码
源码地址 : https://download.csdn.net/download/han1202012/87183425
package kim.hsl.coroutineimport android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlockingclass MainActivity : AppCompatActivity(){val TAG = "MainActivity"override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)runBlocking {// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程val launchJob = launch {// 调用该挂起函数延迟 100 msdelay(100)Log.i(TAG, "launchJob 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务launchJob.join()val launchJob1 = launch {// 调用该挂起函数延迟 100 msdelay(50)Log.i(TAG, "launchJob1 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务launchJob1.join()val launchJob2 = launch {// 调用该挂起函数延迟 100 msdelay(10)Log.i(TAG, "launchJob2 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务launchJob2.join()val asyncDeferred = async {// 调用该挂起函数延迟 100 msdelay(100)Log.i(TAG, "asyncDeferred 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务asyncDeferred.await()val asyncDeferred1 = async {// 调用该挂起函数延迟 100 msdelay(50)Log.i(TAG, "asyncDeferred1 执行完毕")}// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务asyncDeferred1.await()val asyncDeferred2 = async {// 调用该挂起函数延迟 100 msdelay(10)Log.i(TAG, "asyncDeferred2 执行完毕")}}}
}
执行结果 :
23:09:21.239 I launchJob 执行完毕
23:09:21.298 I launchJob1 执行完毕
23:09:21.331 I launchJob2 执行完毕
23:09:21.471 I asyncDeferred 执行完毕
23:09:21.562 I asyncDeferred1 执行完毕
23:09:21.611 I asyncDeferred2 执行完毕
【Kotlin 协程】协程启动 ② ( 多协程控制 | launch 协程执行顺序控制 | Job#join() 函数 | async 协程执行顺序控制 | Deferred#await() 函数 )相关推荐
- Kotlin学习笔记23 协程part3 lambda表达式深入 挂起函数 全局协程
参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 1 lambda表达式深入 /*** lambda 表达式深入* 当函数参数是函数时 并且该函数只有一个参数 可以不传入任 ...
- 【Kotlin 协程】协程取消 ② ( CPU 密集型协程任务取消 | 使用 isActive 判定协程状态 | 使用 ensureActive 函数取消协程 | 使用 yield 函数取消协程 )
文章目录 一.CPU 密集型协程任务取消 二.使用 isActive 判定当前 CPU 密集型协程任务是否取消 三.使用 ensureActive 自动处理协程退出 四.使用 yield 函数检查协程 ...
- 协程入门(一):启动与挂起
什么是协程 协程: 是一种更为灵活高效的"用户线程",能够选择异步还是同步执行,指定运行的线程. 异步.同步编程 : 是指的协程能够选择自身的启动模式,在当前线程堵塞式运行,还是在 ...
- java 协程框架_GitHub - yaozhang0105/dactor: Dactor是基于Java的轻量级同步异步统一处理框架,基于协程思想构建...
DActor Introduction DActor框架基于协程思想设计,可同时支持同步和异步代码,简化在线异步代码的开发,用同步代码的思维来开发异步代码,兼顾异步代码的高并发.无阻塞和同步代码的易读 ...
- 进程池、线程池、回调函数、协程
阅读目录 摘要: 进程池与线程池 同步调用和异步调用 回调函数 协程 一.进程池与线程池: 1.池的概念: 不管是线程还是进程,都不能无限制的开下去,总会消耗和占用资源. 也就是说,硬件的承载能力是有 ...
- go 协程回调函数 传入参数_ECMAScript 6 入门教程—Generator 函数的异步应用
作者 | 阮一峰异步编程对 JavaScript 语言太重要.JavaScript 语言的执行环境是"单线程"的,如果没有异步编程,根本没法用,非卡死不可.本章主要介绍 Gener ...
- python线程的注意点(线程之间执行是无序的、主线程会等待所有的子线程执行结束再结束(守护主线程)、线程之间共享全局变量、线程之间共享全局变量数据出现错误问题(线程等待(join)、互斥锁))
1. 线程的注意点介绍 线程之间执行是无序的 主线程会等待所有的子线程执行结束再结束 线程之间共享全局变量 线程之间共享全局变量数据出现错误问题 2. 线程之间执行是无序的 import thread ...
- 创建一个 Dog 类继承 Thread ,每 2 秒叫一次(汪汪汪!!),创建一个 Cat 实现 Runnable 接口,每 3 秒求抚摸一次(主人快摸摸我!!),主函数(主线程)从 1 输出到 10
题目:创建一个 Dog 类继承 Thread ,每 2 秒叫一次(汪汪汪!!),创建一个 Cat 实现 Runnable 接口,每 3 秒求抚摸一次(主人快摸摸我!!),主函数(主线程)从 1 输出到 ...
- 子线程循环10次,接着主线程循环5次,接着又回到子线程循环10次,接着再回到主线程又循环5次,如此循环50次,请写出程序。
public class ThreadTest { /** * * 子线程循环10次,接着主线程循环5次,接着又回到子线程循环10次,接着再回到主线程又循环5次,如此循环50次,请写出程序. * * ...
最新文章
- 无法加载Dll”ArcGISVersion.dll”:0x8007007E
- python和c语言的对比_类C语言与Python负数除法求值间的差异
- 北京低利用率数据中心将有序关闭腾退
- SSM框架前台传中文到后台乱码问题的解决办法
- spring boot常用注解的作用
- java 如何跟多个字符串比较_Stack Overflow上370万浏览量的一个问题:如何比较Java的字符串...
- 如何得到发送邮件服务器地址(SMTP地址)
- 基于JAVA+SpringMVC+Mybatis+MYSQL的粮店粮食库存管理系统
- java判断三位数的范围代码_java判断三位数的实例讲解
- protobuf根据DebugString字串反解pb对象(及基于此的简单配置实现)
- 解决问题--修改weblogic密码后无法启动以及如何解密weblogic的3DES密文
- php 可逆加密方法
- sparksql处理mysql_Spark记录-SparkSQL远程操作MySQL和ORACLE
- vue 移动端进入页面自动弹出软键盘
- python的flask框架显示柱状图_使用Python的Flask框架,结合Highchart,动态渲染图表...
- 【ENVI】遥感影像的导入与裁剪
- 书摘—慕课革命:互联网如何变革教育?
- Jmeter 环境搭建
- IDEA Ctrl+Alt+L 自定义格式化代码的编码格式
- 美通社发布《2020年亚太地区旅游媒体推介资料包》,揭示疫情下的媒体关注点...