"withContext" 是否创建了一个新协程?

Does "withContext" create a new 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:

Calls the specified suspending block with a given coroutine context, suspends until it completes, and returns the result.

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

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(通过 "launch")

还有两个线程:

  • 主要
  • DefaultDispatcher-worker-1

执行 "withContext" 时不会创建额外的协程。你的两个协程是 "runBlocking" 和 "launch".

线程和协程之间没有一一对应关系。当协程从挂起恢复时,它可以在其他线程上恢复,具体取决于 Dispatcher 给它的内容。

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