协程-基础3

什么是协程作用域(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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 如果英文较好,建议直接阅读原文[https://medium.com/swlh/kotlin-coroutines...
    剑舞潇湘阅读 1,781评论 0 3
  • [TOC] 简介 Coroutines are computer program components that ...
    Whyn阅读 6,175评论 5 15
  • 概述 解释协程 1.协程是轻量级线程(官方表述)可以换个说法,协程就是方法调用封装成类线程的API。方法调用当然比...
    有腹肌的豌豆Z阅读 553评论 0 0
  • 协程(Coroutine) 协程引入 异步加载图片 普通代码:val view = ...loadImageAsy...
    晨起清风阅读 1,380评论 0 1
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,836评论 16 22

友情链接更多精彩内容