协程-基础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

你可能感兴趣的:(协程-基础3)