美文网首页
2.协程的四种启动模式

2.协程的四种启动模式

作者: 学吉他的袁先生 | 来源:发表于2020-07-29 11:54 被阅读0次

1.DEFAULT模式

协程的默认启动模式,launch 调用后,会立即进入待调度状态,一旦调度器 OK 就可以开始执行

suspend fun main(){
    println(1)
    val job = GlobalScope.launch {
        println(2)
    }
    println(3)
    //job.join()
    println(4)
}

没有job.join打印134或者1342
加入job.join输出是1324
取决于 CPU 对于当前线程与后台线程的调度顺序
main运行在ui线程,GlobalScope.launch运行在DefaultDispatcher-worker线程
1.没有job.join()执行流程
先打印1,launch调用后进入待调度状态,但是此时调度器还没有ok
打印3,4,如果运气好的话,会再打印2,然后程序结束取决于调度器ok的时机
2.有job.join()执行流程
先打印1,launch调用后进入待调度状态,但是此时调度器还没有ok
打印3,job.join等待调度器ok并打印2,最后打印4

2.LAZY模式

launch 后并不会有任何调度行为,协程体也不会进入执行状态,直到我们需要它执行的时候

suspend fun main(){
    println(1)
    val job = GlobalScope.launch(start = CoroutineStart.LAZY ) {
        println(2)
    }
    println(3)
//    job.start()
    job.join()
    println(4)
}

输出结果1324
lazy启动模式,launch后没有任何调度,可以通过job.start()或者job.join()来触发调度
1.job.join()执行流程
先打印1,launch调用后不会有调度行为
打印3,job.join()隐式触发调度行为并等待调度器ok打印2
最后打印4
2.job.start()执行流程
先打印1,launch调用后不会有调度行为
打印3,job.start()显式触发调度行为,此时调度器还没ok
打印4,如果运气好的话,会再打印2,然后程序结束

3.ATOMIC模式

launch 调用后,会立即进入待调度状态,跟DEFAULT模式相似
不同的是ATOMIC模式调用cancel,遇到第一个挂起函数之前,它的执行不会取消
协程launch之后会有四种状态
1.待调度状态此时调度器还没有ok
2.调度器ok但还未执行代码
3.开始执行代码
4.代码执行完毕
协程取消时机不同,结果不一样

suspend fun main(){
    println(1)
    val job = GlobalScope.launch(start = CoroutineStart.ATOMIC) {
        println(2)
    }
    job.cancel()
    println(3)
    delay(1000)//为了让2打印出来
}

打印结果123或者132,取决于调度器ok的时机
如果将start改为CoroutineStart.DEFAULT打印结果13
修改上面代码改为写成协程里面有挂起函数

suspend fun main(){
    println(1)
    val job = GlobalScope.launch(start = CoroutineStart.ATOMIC) {
        delay(50)
        println(2)
    }
    job.cancel()
    println(3)
    delay(1000)
}

打印结果13,delay是一个挂起函数,suspend 函数修饰的函数就是挂起函数

4.UNDISPATCHED模式

协程在这种模式下会直接开始在当前线程下执行,直到第一个挂起点, 不经过任何调度器即开始执行协程体。
遇到挂起点之后的执行线程就取决于挂起点本身的逻辑以及上下文当中的调度器

suspend fun main(){
    log(1)
    GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) {
        log(2)
    }
    log(4)
}

打印124,打印1直接打印2因为不经过任何调度器即开始执行协程体
如果将start改为CoroutineStart.DEFAULT打印结果14或者142
修改上面代码加入挂起函数

suspend fun main(){
    log(1)
    GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) {
        log(2)
        delay(200)
        log(3)
    }
    log(4)
    Thread.sleep(500)
    log(5)
}

打印如下
21:11:15:782 [main] 1
21:11:16:015 [main] 2
21:11:16:093 [main] 4
21:11:16:343 [DefaultDispatcher-worker-1] 3
21:11:16:608 [main] 5
delay是挂起函数,3打印的线程DefaultDispatcher-worker-1

相关文章

  • 2.协程的四种启动模式

    1.DEFAULT模式 协程的默认启动模式,launch 调用后,会立即进入待调度状态,一旦调度器 OK 就可以开...

  • 3.协程的调度(1)

    上一张通过四种启动模式,我们知道只有调度器ok,才能执行协程里面的代码,那么协程是如何调度的?下面是Corouti...

  • 破解 Kotlin 协程(3) - 协程调度篇

    关键词:Kotlin 异步编程 协程 上一篇我们知道了协程启动的几种模式,也通过示例认识了 launch 启动协程...

  • 协程启动模式

    开篇前言 kotlin的协程在初学者看来是一个很神奇的东西,居然能做到用同步的代码块实现异步的调用,其实深入了解你...

  • 协程启动模式

    协程启动 我们来看一段最简单的启动协程的方式: 那么这段代码会怎么执行呢?我们说过,启动协程需要三样东西,分别是 ...

  • kotlin协程

    kotlin协程的启动模式 (枚举类CoroutineStart) CoroutineStart.DEFAULT ...

  • 4.协程的异常处理(2)

    异常的传播异常传播是指异常在父子协程中的传播,什么是父子协程,在当前协程中又启动一个协程,那么这个新启动的协程就是...

  • cocore 阅读

    1: coobjc.h 内联函数 启动协程 2.将block转换成OC协程对象 COCoroutine.m 并且创...

  • 协程中launch与withContext都能切换线程,有什么区

    launch、async:启动一个新协程withContext:不启动新协程,在原来的协程中切换线程,需要传入一个...

  • Activity--启动模式

    1.Activity 启动模式 四种启动模式Activity的启动模式有四种:standard、singleTop...

网友评论

      本文标题:2.协程的四种启动模式

      本文链接:https://www.haomeiwen.com/subject/uzdhrktx.html