Я хочу выяснить порядок выполнения и переключение потоков сопрограмм kotlin. Я использовал withContext
для переключения в другой контекст и выполнения задач, требующих времени, чтобы основной поток не блокировался. Но kotlin не переключил контекст, как ожидалось.
Код работает на детской площадке kotlin: https://pl.kotl.in/V0lbCU25K
Случай, который не работает
suspend fun main() = runBlocking {
println("Hello, world!!!")
println(Thread.currentThread().name)
withContext(Dispatchers.IO) {
println("Before heavy load: ${Thread.currentThread().name}")
Thread.sleep(5000)
println("After heavy load: ${Thread.currentThread().name}")
}
println("waiting")
println(Thread.currentThread().name)
}
Выходы
Hello, world!!!
main @coroutine#1
Before heavy load: DefaultDispatcher-worker-1 @coroutine#1
After heavy load: DefaultDispatcher-worker-1 @coroutine#1
waiting
main @coroutine#1
Функция sleep
в вышеприведенных блоках кода выполняется в том же потоке, что и основной поток, и блокирует его.
Следующие случаи соответствуют моим ожиданиям (задача, отнимающая много времени, не блокирует основной поток)
Корпус 1
suspend fun main() = runBlocking {
println("Hello, world!!!")
println(Thread.currentThread().name)
launch {
println("Before heavy load: ${Thread.currentThread().name}")
Thread.sleep(5000)
println("After heavy load: ${Thread.currentThread().name}")
}
println("waiting")
println(Thread.currentThread().name)
}
Выходы
Hello, world!!!
main @coroutine#1
waiting
main @coroutine#1
Before heavy load: main @coroutine#2
After heavy load: main @coroutine#2
Корпус 2
suspend fun main() = runBlocking {
println("Hello, world!!!")
println(Thread.currentThread().name)
launch {
withContext(Dispatchers.IO) {
println("Before heavy load: ${Thread.currentThread().name}")
Thread.sleep(5000)
println("After heavy load: ${Thread.currentThread().name}")
}
}
println("waiting")
println(Thread.currentThread().name)
}
Выходы
Hello, world!!!
main @coroutine#1
waiting
main @coroutine#1
Before heavy load: DefaultDispatcher-worker-1 @coroutine#2
After heavy load: DefaultDispatcher-worker-1 @coroutine#2