Both coroutine builders GlobalScope.launch {} and launch {} are used to start a new coroutine. GlobalScope.launch {} starts a new coroutine in the 'global' scope and launch {} starts a new coroutine in a CoroutineScope. But what does this mean? 
To understand what is happening, we take a look at runBlocking {}. runBlocking {} will block execution (executing the next line of code after runBlocking {}) until all coroutines defined inside it's scope have been completed. For example in the following snippet, the line at 4. will only execute when both coroutines defined inside runBlocking {} have been completed:
fun main() {
    println("1. Let's begin")
    runBlocking {
        launch { 
            delay(1000)
            println("3. coroutine ONE")
        }
        launch { 
            delay(500)
            println("2. coroutine TWO")
        }
    }
    println("4. Only when the children inside runBlocking complete, execution follows on this line")
}
Let try running the same code with GlobalScope.launch {} instead of launch {}:
fun main() {
    println("1. Let's start with GlobalScope.launch {}")
    runBlocking {
        GlobalScope.launch {
            delay(1000)
            println("3. coroutine ONE")
        }
        GlobalScope.launch {
            delay(100)
            println("2. coroutine TWO")
        }
    }
    println("4. This line will execute even if the coroutines inside runBlocking did not complete.")
}
Now the coroutines inside runBlocking {}'s scope did not complete, and execution continued. What is happening here?
runBlocking {} defines a CoroutineScope where coroutines run in. However, the coroutines launched in the above example are running in a separate 'global' scope, where runBlocking has no control over. As far as runBlocking {} knows, there are no coroutines running inside it's scope. 
 

 
    
Top comments (1)
Thank you