[英]The withContext coroutine is not working. Using Kotlin in Android
[英]Coroutine Execution Order using withContext
幾天前我開始研究協程。 我明白了一點,但后來我看到一些代碼行提出了一些問題:
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}")
}
output 是:
before coroutine in main main @coroutine#1
in sub coroutine main @coroutine#2
hello from coroutine DefaultDispatcher-worker-1 @coroutine#1
hello from coutoutine after delay DefaultDispatcher-worker-1 @coroutine#1
after coroutine in main main @coroutine#1
據我了解, launch
會在工作線程上創建一個新的協程,因此主線程上的任何正常 function 都會在啟動完成之前執行。 如果是這樣,我有點困惑為什么withContext
代碼在launch
代碼之前運行。 有人可以解釋嗎?
launch
在工作線程上創建一個新的協程
當你按照這樣的句子構築你的想法時要小心。 協程不像普通代碼那樣在給定線程上運行。 這更像是將線程固定到 CPU 內核。 固定線程不擁有內核,操作系統只是確保,無論何時掛起然后恢復它,它都會將其調度到同一個 CPU 內核。
如果您使用“將線程調度到 CPU 內核”范例通過您的代碼 go,您可以輕松地看到您的 output 是如何有意義的:
runBlocking { // Create a context within which "threads" are pinned
// to a single "core", let's call it "Main Core"
launch { // Start another "thread" pinned to "Main Core". The "thread" is
// in a suspended state, waiting for "Main Core" to get free
println("in sub coroutine ${Thread.currentThread().name}")
}
// `launch` is just a function, it completed after creating the new "thread",
// move on to the code below it
println("before coroutine in main ${Thread.currentThread().name}")
// Start a context where "threads" are pinned to another "core", the
// "IO Core". It executes its "threads" concurrently to "Main Core".
// However, the particular "thread" that creates the context gets suspended
// until it is done. Other "threads" pinned to "Main Core" can run.
withContext(Dispatchers.IO) {
println("hello from coroutine ${Thread.currentThread().name}")
delay(1500)
println("hello from coutoutine after delay ${Thread.currentThread().name}")
}
// Now the "thread" that created the "IO Core" context can go on.
println("after coroutine in main ${Thread.currentThread().name}")
}
在這張圖片中,您只需添加一個事實,即“OS”無法搶先掛起“線程”,只有當“線程”掛起自己時,“OS”才能接管以做出另一個調度決定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.