协程常用词

协程特性


// 几个作用域中的问题
    private fun testCoroutineScope1() = runBlocking {
        println("testCoroutineScope")
        launch {
            delay(800L)
            println("${System.currentTimeMillis()} launch this : $this  coroutine context: ${this.coroutineContext}")
        }

        coroutineScope {
            launch {
                delay(500)
                println("${System.currentTimeMillis()} coroutineScope inner this $this launch context: ${this.coroutineContext}")
            }

            delay(1100)
            println("${System.currentTimeMillis()} coroutineScope this $this context ${this.coroutineContext}")
        }

        println("${System.currentTimeMillis()} runBlocking this $this context ${this.coroutineContext}")
    }

// 输出结果,根据delay的时间不同,先后按照delay之后执行的
testCoroutineScope
// coroutineScope inner 里面的 context 是 StandaloneCoroutine
1629689386348 coroutineScope inner this StandaloneCoroutine{Active}@4f8e5cde launch context: [StandaloneCoroutine{Active}@4f8e5cde, BlockingEventLoop@759ebb3d]
// 最外层 launch StandaloneCoroutine
1629689386648 launch this : StandaloneCoroutine{Active}@4cdf35a9  coroutine context: [StandaloneCoroutine{Active}@4cdf35a9, BlockingEventLoop@759ebb3d]
// coroutineScope 使用的上下文作用域为 ScopeCoroutine,与 runBlocking 功能类似,等待内部执行完毕才会关闭,但是他会挂起,而不是阻塞
1629689386945 coroutineScope this ScopeCoroutine{Active}@4c98385c context [ScopeCoroutine{Active}@4c98385c, BlockingEventLoop@759ebb3d]
// runBlocking 没有使用 launch 的上下文为 BlockingCoroutine,默认是主线程的且会阻塞主线程
1629689386946 runBlocking this BlockingCoroutine{Active}@5fcfe4b2 context [BlockingCoroutine{Active}@5fcfe4b2, BlockingEventLoop@759ebb3d]


suspend 用法示例


    suspend fun doWorld() {
        delay(500)
        println("World!")
    }

// 这里如果不加 launch 就会直接输出,实际上 doWorld 和普通函数不同就是加上 suspend 关键字,但是没有 launch 就不会产生 Job 也就无法产生 delay 挂起的效果。
    fun doHello() = runBlocking {
        launch {
            doWorld()
        }
        println("hello")
    }


// launch 定义,可以看到这里最终是生成了一个 Job ,这个 Job 是一个协程
public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}