I'm trying to understand runBlocking in kotlin.
println("before runBlocking ${Thread.currentThread().name}")
runBlocking { // but this expression blocks the main thread
delay(2000L) // non blocking
println("inside runBlocking ${Thread.currentThread().name}")
delay(2000L)
}
println("after runBlocking ${Thread.currentThread().name}")
Output
before runBlocking main
inside runBlocking main
after runBlocking main
Kotlin Says
- runBlocking -
Runs a new coroutineandblocks the current threadinterruptibly until its completion- The main thread invoking runBlocking blocks until the coroutine inside runBlocking completes.
point 1 :- if runBlocking blocked the main thread in above example. Then inside runBlocking how i get the main thread again.
point 2 :- if Runs a new coroutine is true in above statement, then why it didn't create new coroutine inside runBlocking.
The signature of runBlocking (doc) is
fun <T> runBlocking(
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.() -> T
): T (source)
If you see the context param, it has a default of an EmptyCoroutineContext. Hence when you don't pass a specific context, the default value is an event loop on the current thread. Since the current thread before running the runBlocking block was the main thread, whatever you ran inside the block is still on the main thread.
If you pass a coroutine context as below, you would have the block inside runBlocking running in a different thread.
println("before runBlocking ${Thread.currentThread().name}")
runBlocking(Dispatchers.Default) {
delay(2000L)
println("inside runBlocking ${Thread.currentThread().name}")
delay(2000L)
}
println("after runBlocking ${Thread.currentThread().name}")
Output
before runBlocking main
inside runBlocking DefaultDispatcher-worker-1
after runBlocking main
Or if you launch runBlocking without passing the context, but launch a coroutine inside as below, you would see it running on the different thread.
println("before runBlocking ${Thread.currentThread().name}")
runBlocking {
println("inside runBlocking ${Thread.currentThread().name}")
delay(2000L)
CoroutineScope(Dispatchers.Default).launch {
println("inside runBlocking coroutineScope ${Thread.currentThread().name}")
}
delay(2000L)
}
println("after runBlocking ${Thread.currentThread().name}")
Output
before runBlocking main
inside runBlocking main
inside runBlocking coroutineScope DefaultDispatcher-worker-1
after runBlocking main
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With