Kotlin: 协程的四种启动模式(CoroutineStart)

点击查看CoroutineStart英文文档

创建协程的三种方式

  1. runBlocking
    运行一个协程并且会阻塞当前线程,直到它完成。

  2. launch
    启动一个新的协程,不会阻塞当前线程,并且返回一个Job,可以取消。

  3. async
    async和await是两个函数,这两个函数在我们使用过程中一般都是成对出现的。
    async用于启动一个异步的协程任务,await用于去得到协程任务结束时返回的结果,结果是通过一个Deferred对象返回的。

    在概念上,async 就类似于 launch。它启动了一个单独的协程,这是一个轻量级的线程并与其它所有的协程一起并发的工作。不同之处在于 launch 返回一个 Job 并且不附带任何结果值,而 async 返回一个 Deferred ------ 一个轻量级的非阻塞 future, 这代表了一个将会在稍后提供结果的 promise。可以使用 .await() 在一个延期的值上得到它的最终结果, 但是 Deferred 也是一个 Job,所以如果需要的话,你可以取消它。

CoroutineStart源码

协程的四种启动模式一:DEFAULT

Default------根据上下文立即调度协程执行。

如果协程上下文的[CoroutineDispatcher]从[CoroutineDispatcher. isdispatchneeded]返回' true '

函数,然后协程代码被调度以供稍后执行,而代码被调度

被调用的协程构建器继续执行。

注意[Dispatchers。unconstrained总是从它的[CoroutineDispatcher.isDispatchNeeded]返回false

函数,所以用[Dispatchers. *]启动协程。unconstrained [DEFAULT]与使用[un分派]相同。

如果协程[Job]在它有机会开始执行之前被取消,那么它将不会启动它的执行,但将以异常完成。

在挂起点的协同程序的可取消性取决于的具体实现细节暂停功能。使用[suspenpendcancellablecoroutine]实现可取消的挂起函数。

示例

bash 复制代码
fun main() = runBlocking {
    val job = launch (start = CoroutineStart.DEFAULT){
        println("开始执行耗时操作...")
        delay(2000L)
        println("耗时操作结束")
    }
    delay(1000L)
    job.cancel()
    println("任务取消了")
}

运行结果

协程的四种启动模式二:LAZY

仅在需要时才惰性地启动协程。

详细信息请参见相应协程构建器的文档

(如[launch][CoroutineScope])。launch]和[async][coroutincope .async])。

如果协程[Job]在它有机会开始执行之前被取消,那么它将不会启动它的执行,但将以异常完成。

bash 复制代码
fun main() = runBlocking {
    val job = async  (start = CoroutineStart.LAZY){
        println("开始执行耗时操作...")
        delay(2000L)
        println("耗时操作结束")
    }
    delay(1000L)
    job.cancel()
    println("任务取消了")
    job.await()
}

运行结果

协程的四种启动模式三:ATOMIC

自动地(即,以一种不可取消的方式)根据上下文调度协程的执行。

这类似于[DEFAULT],但是协程在开始执行之前不能被取消。

在挂起点的协程是否可取消,取决于挂起函数如[DEFAULT]。

@ExperimentalCoroutinesApi //从1.0.0开始,没有稳定性的ETA

bash 复制代码
fun main() = runBlocking {
    val job = async(start = CoroutineStart.ATOMIC) {
        println("开始执行耗时操作...")
        //在挂起点之前不会被取消
        delay(2000L)//这里就是一个挂起点, delay是挂起函数
        println("耗时操作结束")
    }
    delay(1000L)
    job.cancel()
    println("任务取消了")
}

运行结果

协程的四种启动模式四:UNDISPATCHED

立即执行协程,直到它在当前线程中的第一个挂起点

协程是使用[dispatchers . unconstrained]启动的。但是,当协程从暂停状态恢复时

根据上下文中的[CoroutineDispatcher]进行分派。

这类似于[ATOMIC],因为协程即使已经被取消也会开始执行。

但不同之处在于它在同一个线程中开始执行。

在挂起点的协程是否可取消,取决于挂起函数如[DEFAULT]。

注:这是一个实验性api。当使用此模式时,协程的执行语义可能会在将来发生变化。

@ExperimentalCoroutinesApi //从1.0.0开始,没有稳定性的ETA

bash 复制代码
fun main() = runBlocking {
    val job = async(context = Dispatchers.IO, start = CoroutineStart.UNDISPATCHED) {
        println("开始执行耗时操作... ${Thread.currentThread().name}")
        //在挂起点之前不会被取消
        delay(2000L)//这里就是一个挂起点, delay是挂起函数
        println("耗时操作结束...${Thread.currentThread().name}")
    }
    delay(1000L)
    job.cancel()
    println("任务取消了...${Thread.currentThread().name}")
}

运行结果

从上图可以看到, async(context = Dispatchers.IO, start = CoroutineStart.UNDISPATCHED) ,但是还在主线程执行的。

推荐

Kotlin:组合挂起函数

相关推荐
yueqc110 分钟前
Kotlin 协程 Flow 操作符总结
kotlin·协程·flow
fanged2 小时前
天马G前端的使用
android·游戏
molong9316 小时前
Kotlin 内联函数、高阶函数、扩展函数
android·开发语言·kotlin
叶辞树7 小时前
Android framework调试和AMS等服务调试
android
慕伏白9 小时前
【慕伏白】Android Studio 无线调试配置
android·ide·android studio
低调小一10 小时前
Kuikly 小白拆解系列 · 第1篇|两棵树直调(Kotlin 构建与原生承载)
android·开发语言·kotlin
跟着珅聪学java10 小时前
spring boot 整合 activiti 教程
android·java·spring
川石课堂软件测试11 小时前
全链路Controller压测负载均衡
android·运维·开发语言·python·mysql·adb·负载均衡
2501_9159214312 小时前
iOS 26 电耗监测与优化,耗电问题实战 + 多工具 辅助策略
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_9159214312 小时前
苹果软件混淆与 iOS 应用加固白皮书,IPA 文件加密、反编译防护与无源码混淆方案全解析
android·ios·小程序·https·uni-app·iphone·webview