“ withContext”会创建新的协程吗?

时间:2020-02-26 18:31:56

标签: kotlin coroutine

我有以下代码:

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        println("in sub coroutine ${Thread.currentThread().name}")
    }
    println("before coroutine in main ${Thread.currentThread().name}")
    withContext(Dispatchers.IO) {
        println("hello from coroutine ${Thread.currentThread().name}")
        delay(1500)
        println("hello from coutoutine after delay ${Thread.currentThread().name}")
    }
    println("after coroutine in main ${Thread.currentThread().name}")
}

输出为:

before coroutine in main main @coroutine#1
hello from coroutine DefaultDispatcher-worker-1 @coroutine#1
in sub coroutine main @coroutine#2
hello from coutoutine after delay DefaultDispatcher-worker-1 @coroutine#1
after coroutine in main main @coroutine#1

我的理解是withContext将代码切换到新的上下文,其中代码在另一个线程中执行,并且当前协程被挂起,直到新线程中的代码完成。但是最初的定义并没有说明创建新的协程。

Original definition来自kotlin.github.io:

使用给定的协程上下文调用指定的暂停块,直到完成为止暂停并返回结果。

2 个答案:

答案 0 :(得分:4)

线程和协程之间没有一对一的对应关系。当协程从暂停状态恢复时,它可以在其他线程上恢复,这取决于分派器给它的服务。

launchasync创建新的协程。 withContext不会创建新的协程,它只会移动现有协程的上下文,这就是为什么它是一个暂停函数的原因(与launchasync不同)。

答案 1 :(得分:1)

我相信您只是误读了您的输出。

before coroutine in main main @coroutine#1
hello from coroutine DefaultDispatcher-worker-1 @coroutine#1
in sub coroutine main @coroutine#2
hello from coutoutine after delay DefaultDispatcher-worker-1 @coroutine#1
after coroutine in main main @coroutine#1

在此输出中,您有2个协程:

  • @ coroutine#1(通过“ runBlocking”)
  • @ coroutine#2(通过“启动”)

还有两个线程:

  • 主要
  • DefaultDispatcher-worker-1

执行“ withContext”时,不会创建其他协程。您的两个协程是“ runBlocking”和“ launch”。