Bahaa
Bahaa

Reputation: 1767

Understanding difference in behavior between runBlocking and coroutineScope

In the Kotlin Coroutines guide, here, while explaining the difference between runBlocking and coroutineScope, it says:

... The main difference is that the runBlocking method blocks the current thread for waiting, while coroutineScope just suspends, releasing the underlying thread for other usages. ...

which is understandable. However, in the sample code listed there:

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    launch { 
        delay(200L)
        println("Task from runBlocking")
    }
    
    coroutineScope { // Creates a coroutine scope
        launch {
            delay(500L) 
            println("Task from nested launch")
        }
    
        delay(100L)
        println("Task from coroutine scope") // This line will be printed before the nested launch
    }
    
    println("Coroutine scope is over") // This line is not printed until the nested launch completes
}

which produces the following output:

Task from coroutine scope
Task from runBlocking
Task from nested launch
Coroutine scope is over

replacing the coroutineScope with a runBlocking to be:

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    launch { 
        delay(200L)
        println("Task from runBlocking")
    }
    
    runBlocking { // instead of coroutineScope, previously
        launch {
            delay(500L) 
            println("Task from nested launch")
        }
    
        delay(100L)
        println("Task from coroutine scope") // This line will be printed before the nested launch
    }
    
    println("Coroutine scope is over") // This line is not printed until the nested launch completes
}

changes nothing in the output. I expected it to produce the following output instead, since the nested runBlocking would block until its block finishes including all child coroutines:

Task from coroutine scope
Task from nested launch
Task from runBlocking
Coroutine scope is over

Could someone explain this behavior? What am I overseeing here?

Upvotes: 1

Views: 1345

Answers (2)

araqnid
araqnid

Reputation: 133792

Having a runBlocking within a runBlocking is .. unusual. It's more usual that runBlocking is only the very outer thing. In fact the implementation of runBlocking will use the event loop of the outer runBlocking rather than creating a new one, so it effectively is behaving like coroutineScope in this case.

Source: https://github.com/Kotlin/kotlinx.coroutines/blob/dda99e21f45f65eb540ccf4d5e82faf7559bc9e5/kotlinx-coroutines-core/jvm/src/Builders.kt#L46

Upvotes: 3

H.D.
H.D.

Reputation: 1413

runBlocking just blocks current thread until the block passed to it returns. It doesn't affect how the block is executed.

Upvotes: 0

Related Questions