协程-基础3

作者: 有腹肌的豌豆Z | 来源:发表于2021-02-02 14:00 被阅读0次

    什么是协程作用域(Coroutine Scope)?

    协程作用域是协程运行的作用范围,换句话说,如果这个作用域销毁了,那么里面的协程也随之失效。就好比变量的作用域。

    { // scope start
        int a = 100;
    } // scope end
    println(a); // what is a?
    

    协程作用域也是这样一个作用,可以用来确保里面的协程都有一个作用域的限制。

    一个经典的示例就是,比如我们要在Android上使用协程,但是我们不希望Activity销毁了,我的协程还在悄咪咪的干一些事情,我希望它能停止掉。

    class MyActivity : AppCompatActivity(), CoroutineScope by MainScope() {
        // ....
    }
    

    这样,里面运行的协程就会随着Activity的销毁而销毁。

    launch的返回值:Job

    回到launch的话题,launch启动后,会返回一个Job对象,表示这个启动的协程,我们可以方便的通过这个Job对象,取消,等待这个协程。

    fun main() {
    
        runBlocking(Dispatchers.IO) {
    
            println("job1 开始了")
    
            val job1 = launch {
                for (i in 0..1) {
                    println("normal launch $i ${Thread.currentThread().name} #####")
                    delay(100)
                }
            }
    
            println("job1 开始了")
    
            val job2 = launch {
                for (i in 0..1) {
                    println("normal launch $i ${Thread.currentThread().name} -----")
                    delay(100)
                }
            }
    
            job1.join()
            job2.join()
    
            println("all job finished")
        }
    }
    

    job1 开始了
    job1 开始了
    normal launch 0 DefaultDispatcher-worker-2 #####
    normal launch 0 DefaultDispatcher-worker-4 -----
    normal launch 1 DefaultDispatcher-worker-2 #####
    normal launch 1 DefaultDispatcher-worker-4 -----
    all job finished

    使用job的join方法,来等待这个协程执行完毕。这个和Thread的join方法语义一样。

    async:启动协程的另一种姿势

    launch启动一个协程后,会返回一个Job对象,这个Job对象不含有任何数据,它只是表示启动的协程本身,我们可以通过这个Job对象来对协程进行控制。

    假设这样一种场景,我需要同时启动两个协程来搞点事,然后它们分别都会计算出一个Int值,当两个协程都做完了之后,我需要将这两个Int值加在一起并输出。

    async的返回值依然是个Job对象,但它可以带上返回值。

    fun main() {
    
        runBlocking(Dispatchers.IO) {
    
            println("job1 开始了")
    
            //
            val job1 = async {
                for (i in 0..2) {
                    println("normal launch $i ${Thread.currentThread().name} #####")
                    delay(100)
                }
                10 // TODO 注意这里的返回值
            }
    
            println("job2 开始了")
    
            val job2 = async {
                for (i in 0..2) {
                    println("normal launch $i ${Thread.currentThread().name} -----")
                    delay(100)
                }
                20 // TODO 注意这里的返回值
            }
    
            println(job1.await() + job2.await())
    
            println("all job finished")
        }
    }
    
    

    job1 开始了
    job2 开始了
    normal launch 0 DefaultDispatcher-worker-3 #####
    normal launch 0 DefaultDispatcher-worker-2 -----
    normal launch 1 DefaultDispatcher-worker-3 #####
    normal launch 1 DefaultDispatcher-worker-2 -----
    normal launch 2 DefaultDispatcher-worker-2 #####
    normal launch 2 DefaultDispatcher-worker-5 -----
    30
    all job finished

    相关文章

      网友评论

        本文标题:协程-基础3

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