Kotlin-Coroutines

Coroutines中的Structured concurren

2021-02-10  本文已影响0人  From64KB

Coroutine scope负责在不同的coroutine之间形成结构化和父-子关系(这里有点抽象,稍后会解释什么是结构化和父-子关系),通常会从scope中启动一个新的coroutine。Coroutine context中保存了运行coroutine需要的信息,比如coroutine运行的线程等。
通常使用launch,async,runBlocking启动新的coroutine,这三个会自动创建对定的scope。这三个方法都会接受一个lambda作为参数,隐式的receiver接受类型是CoroutineScope

launch { /* this: CoroutineScope */
}

新的coroutine只可以在scope中被启动。launchasyncCoroutineScope的扩展方法,所以在调用他们之前必须显式或隐式地传递receiver。但是runBlocking中的coroutine是唯一的例外:runBlocking是一个top-level函数。但是因为runBlocking会阻塞当前线程,所以主要被用在main方法或者测试中作为一个桥梁方法。在launch,async或者runBlocking里启动的coroutine会自动的从属于对应的scope。

fun main() = runBlocking { /* this: CoroutineScope */
    launch { /* ... */ }
    // the same as:    
    this.launch { /* ... */ }
}

runBlocking中调用launch时会其实是隐式的调用CoroutineScope.launch,这和下面this.launch是等价的。

外面coroutine(runBlocking)和内部嵌套调用的coroutine(上面的launch)形成了父-子关系。

在不启动coroutine的情况下也可以创建新的scope,通过coroutineScope可以做到这一点。在不访问外部scope的情况下在suspend方法中创建新的coroutine,这个coroutine会自动的成为外部调用这个suspend方法所在的scope形成父-子关系。

使用GlobalScope.async或者GlobalScope.launch也可以创建全局scope的top-level 的coroutine。

上面说的就是父-子关系,提供结构化的机制称为“结构化并发(structured concurrency)”,这样的机制有以下优点:

但是如果使用的是上面提到的GlobalScope.async来启动coroutine就会破坏这种结构化的关系。因为通过GlobalScope.async启动的coroutine是完全独立的,和应用的生命周期绑定。

上一篇下一篇

猜你喜欢

热点阅读