“withContext”是否创建一个新的协程?

Tar*_*wla 4 coroutine kotlin

我有以下代码:

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}")
}
Run Code Online (Sandbox Code Playgroud)

输出是:

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}")
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,withContext将代码切换到新的上下文,其中代码在不同的线程中执行,并且当前协程被挂起,直到新线程中的代码完成。但最初的定义并没有提到任何关于创建新协程的内容。

来自 kotlin.github.io 的原始定义

使用给定的协程上下文调用指定的挂起块,挂起直到完成,然后返回结果。

Ten*_*r04 6

线程和协程之间不存在一一对应的关系。当协程从挂起状态恢复时,它可以在其他线程上恢复,具体取决于调度程序提供的内容。

launchasync创建新的协程。withContext不会创建新的协程,它只会改变现有协程的上下文,这就是为什么它是一个挂起函数(与launch和不同async)。

  • 我认为他们的术语可以做一些工作。他们说协程被暂停并稍后恢复,但实际上同一个协程正在做其他工作。所以“协程”的具体含义有点模糊。该函数的 Kdoc 说“挂起直到完成”,但没有说明挂起的“内容”。它挂起调用它的挂起函数。 (2认同)
  • 典型的函数从头到尾运行并完全占用其运行的线程。挂起函数会在挂起时释放其线程(通过调用其他挂起函数来实现),并且它可能会在其他线程上恢复,具体取决于当前调度程序的行为。术语“协程”类似于“线程”,因为它是您编程要发生的一系列事情,但不是因为它是一个可以让事情发生的对象。 (2认同)
  • 这就是为什么我说我认为协程这个术语是含糊不清的。不存在称为协程的实际对象。它只是描述执行流程的术语。我们说协程被挂起函数挂起,但挂起函数本身仍在该协程中运行,并且可能在第一次挂起恢复之前再次挂起它。 (2认同)