我有以下代码:
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:
使用给定的协程上下文调用指定的暂停块,直到完成为止暂停并返回结果。
答案 0 :(得分:4)
线程和协程之间没有一对一的对应关系。当协程从暂停状态恢复时,它可以在其他线程上恢复,这取决于分派器给它的服务。
launch
和async
创建新的协程。 withContext
不会创建新的协程,它只会移动现有协程的上下文,这就是为什么它是一个暂停函数的原因(与launch
和async
不同)。
答案 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个协程:
还有两个线程:
执行“ withContext”时,不会创建其他协程。您的两个协程是“ runBlocking”和“ launch”。