文章目录

  • 一、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() 函数 )相关推荐

  1. Kotlin学习笔记23 协程part3 lambda表达式深入 挂起函数 全局协程

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 1 lambda表达式深入 /*** lambda 表达式深入* 当函数参数是函数时 并且该函数只有一个参数 可以不传入任 ...

  2. 【Kotlin 协程】协程取消 ② ( CPU 密集型协程任务取消 | 使用 isActive 判定协程状态 | 使用 ensureActive 函数取消协程 | 使用 yield 函数取消协程 )

    文章目录 一.CPU 密集型协程任务取消 二.使用 isActive 判定当前 CPU 密集型协程任务是否取消 三.使用 ensureActive 自动处理协程退出 四.使用 yield 函数检查协程 ...

  3. 协程入门(一):启动与挂起

    什么是协程 协程: 是一种更为灵活高效的"用户线程",能够选择异步还是同步执行,指定运行的线程. 异步.同步编程 : 是指的协程能够选择自身的启动模式,在当前线程堵塞式运行,还是在 ...

  4. java 协程框架_GitHub - yaozhang0105/dactor: Dactor是基于Java的轻量级同步异步统一处理框架,基于协程思想构建...

    DActor Introduction DActor框架基于协程思想设计,可同时支持同步和异步代码,简化在线异步代码的开发,用同步代码的思维来开发异步代码,兼顾异步代码的高并发.无阻塞和同步代码的易读 ...

  5. 进程池、线程池、回调函数、协程

    阅读目录 摘要: 进程池与线程池 同步调用和异步调用 回调函数 协程 一.进程池与线程池: 1.池的概念: 不管是线程还是进程,都不能无限制的开下去,总会消耗和占用资源. 也就是说,硬件的承载能力是有 ...

  6. go 协程回调函数 传入参数_ECMAScript 6 入门教程—Generator 函数的异步应用

    作者 | 阮一峰异步编程对 JavaScript 语言太重要.JavaScript 语言的执行环境是"单线程"的,如果没有异步编程,根本没法用,非卡死不可.本章主要介绍 Gener ...

  7. python线程的注意点(线程之间执行是无序的、主线程会等待所有的子线程执行结束再结束(守护主线程)、线程之间共享全局变量、线程之间共享全局变量数据出现错误问题(线程等待(join)、互斥锁))

    1. 线程的注意点介绍 线程之间执行是无序的 主线程会等待所有的子线程执行结束再结束 线程之间共享全局变量 线程之间共享全局变量数据出现错误问题 2. 线程之间执行是无序的 import thread ...

  8. 创建一个 Dog 类继承 Thread ,每 2 秒叫一次(汪汪汪!!),创建一个 Cat 实现 Runnable 接口,每 3 秒求抚摸一次(主人快摸摸我!!),主函数(主线程)从 1 输出到 10

    题目:创建一个 Dog 类继承 Thread ,每 2 秒叫一次(汪汪汪!!),创建一个 Cat 实现 Runnable 接口,每 3 秒求抚摸一次(主人快摸摸我!!),主函数(主线程)从 1 输出到 ...

  9. 子线程循环10次,接着主线程循环5次,接着又回到子线程循环10次,接着再回到主线程又循环5次,如此循环50次,请写出程序。

    public class ThreadTest { /** * * 子线程循环10次,接着主线程循环5次,接着又回到子线程循环10次,接着再回到主线程又循环5次,如此循环50次,请写出程序. * * ...

最新文章

  1. 无法加载Dll”ArcGISVersion.dll”:0x8007007E
  2. python和c语言的对比_类C语言与Python负数除法求值间的差异
  3. 北京低利用率数据中心将有序关闭腾退
  4. SSM框架前台传中文到后台乱码问题的解决办法
  5. spring boot常用注解的作用
  6. java 如何跟多个字符串比较_Stack Overflow上370万浏览量的一个问题:如何比较Java的字符串...
  7. 如何得到发送邮件服务器地址(SMTP地址)
  8. 基于JAVA+SpringMVC+Mybatis+MYSQL的粮店粮食库存管理系统
  9. java判断三位数的范围代码_java判断三位数的实例讲解
  10. protobuf根据DebugString字串反解pb对象(及基于此的简单配置实现)
  11. 解决问题--修改weblogic密码后无法启动以及如何解密weblogic的3DES密文
  12. php 可逆加密方法
  13. sparksql处理mysql_Spark记录-SparkSQL远程操作MySQL和ORACLE
  14. vue 移动端进入页面自动弹出软键盘
  15. python的flask框架显示柱状图_使用Python的Flask框架,结合Highchart,动态渲染图表...
  16. 【ENVI】遥感影像的导入与裁剪
  17. 书摘—慕课革命:互联网如何变革教育?
  18. Jmeter 环境搭建
  19. IDEA Ctrl+Alt+L 自定义格式化代码的编码格式
  20. 美通社发布《2020年亚太地区旅游媒体推介资料包》,揭示疫情下的媒体关注点...

热门文章

  1. Source Insight利用宏文件实现多行快速注释以及其他超级好用的功能
  2. JAVA基础 装箱类型
  3. 华为软件精英挑战赛2015
  4. 他通过使用计算机解决了这个问题翻译,科技英语翻译练习答案重排版.doc
  5. CSS新手入门教程~~~~
  6. 查看MDB格式文件数据表
  7. 视频教程-2019版抓包分析-Wireshark从入门到精通【进阶篇】-其他
  8. SAP中科目余额后台表GLT0
  9. select实现延时函数
  10. A side-by-side LYSOGAGG phoswich detector aiming for SPECT imaging