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 coroutine
andblocks the current thread
interruptibly 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