Kotlin 协程协程启动 ② ( 多协程控制 | launch 协程执行顺序控制 | Job#join() 函数 | async 协程执行顺序控制 | Deferred#await() 函数 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 协程协程启动 ② ( 多协程控制 | launch 协程执行顺序控制 | Job#join() 函数 | async 协程执行顺序控制 | Deferred#await() 函数 )相关的知识,希望对你有一定的参考价值。
文章目录
源码地址 : https://download.csdn.net/download/han1202012/87183425
一、launch 协程执行顺序控制
如果需要通过 launch 协程构建器 启动多个协程 , 后面的协程需要等待前面的协程执行完毕 , 在启动靠后的协程 , 实现方案如下 :
调用 Job#join() 函数 , 可以挂起协程 , 等待 launch 中协程体内的任务执行完毕 , 再执行后面的协程任务 ;
代码示例 : 下面的代码中 , 先执行 launchJob 协程 , 调用 launchJob.join() 函数会挂起协程 , 该 launchJob 协程任务执行完毕后 , 才会执行后面的 launch 协程任务 ;
runBlocking
// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程
val launchJob = launch
// 调用该挂起函数延迟 100 ms
delay(100)
Log.i(TAG, "launchJob 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
launchJob.join()
val launchJob1 = launch
// 调用该挂起函数延迟 100 ms
delay(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.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
class MainActivity : AppCompatActivity()
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking
// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程
val launchJob = launch
// 调用该挂起函数延迟 100 ms
delay(100)
Log.i(TAG, "launchJob 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
launchJob.join()
val launchJob1 = launch
// 调用该挂起函数延迟 100 ms
delay(50)
Log.i(TAG, "launchJob1 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
launchJob1.join()
val launchJob2 = launch
// 调用该挂起函数延迟 100 ms
delay(10)
Log.i(TAG, "launchJob2 执行完毕")
二、async 协程执行顺序控制
如果需要通过 async 协程构建器 启动多个协程 , 后面的协程需要等待前面的协程执行完毕 , 在启动靠后的协程 , 实现方案如下 :
调用 Deferred#await() 函数 , 可以挂起协程 , 等待 async 中协程体内的任务执行完毕 , 再执行后面的协程任务 ;
代码示例 : 下面的代码中 , 先执行 asyncDeferred 协程 , 调用 asyncDeferred.await() 函数会挂起协程 , 该 asyncDeferred 协程任务执行完毕后 , 才会执行后面的 async 协程任务 ;
runBlocking
// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程
val asyncDeferred = async
// 调用该挂起函数延迟 100 ms
delay(100)
Log.i(TAG, "asyncDeferred 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
asyncDeferred.await()
val asyncDeferred1 = async
// 调用该挂起函数延迟 100 ms
delay(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.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
class MainActivity : AppCompatActivity()
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking
// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程
val asyncDeferred = async
// 调用该挂起函数延迟 100 ms
delay(100)
Log.i(TAG, "asyncDeferred 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
asyncDeferred.await()
val asyncDeferred1 = async
// 调用该挂起函数延迟 100 ms
delay(50)
Log.i(TAG, "asyncDeferred1 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
asyncDeferred1.await()
val asyncDeferred2 = async
// 调用该挂起函数延迟 100 ms
delay(10)
Log.i(TAG, "asyncDeferred2 执行完毕")
执行结果 :
三、完整代码
源码地址 : https://download.csdn.net/download/han1202012/87183425
package kim.hsl.coroutine
import 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.runBlocking
class MainActivity : AppCompatActivity()
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking
// 调用 runBlocking 函数 , 可以将 主线程 包装成 协程
val launchJob = launch
// 调用该挂起函数延迟 100 ms
delay(100)
Log.i(TAG, "launchJob 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
launchJob.join()
val launchJob1 = launch
// 调用该挂起函数延迟 100 ms
delay(50)
Log.i(TAG, "launchJob1 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
launchJob1.join()
val launchJob2 = launch
// 调用该挂起函数延迟 100 ms
delay(10)
Log.i(TAG, "launchJob2 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
launchJob2.join()
val asyncDeferred = async
// 调用该挂起函数延迟 100 ms
delay(100)
Log.i(TAG, "asyncDeferred 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
asyncDeferred.await()
val asyncDeferred1 = async
// 调用该挂起函数延迟 100 ms
delay(50)
Log.i(TAG, "asyncDeferred1 执行完毕")
// 挂起协程 , 等待协程执行完毕会后再执行后面的协程任务
asyncDeferred1.await()
val asyncDeferred2 = async
// 调用该挂起函数延迟 100 ms
delay(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 协程协程启动 ⑤ ( 协程作用域构建器 | runBlocking 函数 | coroutineScope 函数 | supervisorScope 函数 )
Kotlin 协程协程启动 ⑤ ( 协程作用域构建器 | runBlocking 函数 | coroutineScope 函数 | supervisorScope 函数 )
Kotlin 协程协程异常处理 ② ( SupervisorJob 协程 | supervisorScope 协程作用域构建器函数 )
Kotlin 协程协程异常处理 ② ( SupervisorJob 协程 | supervisorScope 协程作用域构建器函数 )