Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

kotlin coroutines precedence of execution

I need help understanding the outcome of the following 2 pieces of code

1st snippet

fun main() = runBlocking { 
    launch {
        println("Task from runBlocking")
    }

    coroutineScope { 
        launch {
            println("Task from nested launch")
        }

        println("Task from coroutine scope")
    }

    println("Coroutine scope is over")
}

And, the 2nd snippet

fun main() = runBlocking { 
    launch {
        println("Task from runBlocking")
    }

    println("Coroutine scope is over") 
}

The outcome of the 1st snippet is:

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

The outcome of the 2nd snippet is:

Coroutine scope is over
Task from runBlocking

So, the question is why were the statements printed in that order?

like image 265
a fair player Avatar asked Oct 26 '25 11:10

a fair player


1 Answers

For the 1st snippet you are using coroutineScope which, as you can see from the documentation is defined as a suspend function, so it's blocking the current thread and "Coroutine scope is over" is not printed until coroutineScope block has completed.

For the 2nd snippet the string "Coroutine scope is over" is printed before "Task from run blocking" because its println it's executed in the main thread, and launch which runs in a worker thread has not finished yet its job.

fun mainOne() = runBlocking {
  launch {
      println("Task from runBlocking")
  }

  // coroutineScope is defined as a suspend function, so it's blocking the current thread
  coroutineScope {

      launch {
          // worker thread, slower than main thread, printed after "Task from coroutine scope"
          println("Task from nested launch")
      }
      // main thread, printed before "Task from nested launch" within CoroutineScope
      println("Task from coroutine scope")
  }

  // main thread is now free to run and it prints the string below
  println("Coroutine scope is over")
}


fun mainTwo() = runBlocking {
    launch {
        // worker thread, slower than main thread, printed after "Coroutine scope is over" due to concurrency
        println("Task from runBlocking")
    }
    // main thread is running and prints the string below before launch job has finished.
    // If you put a delay here you'll notice that launch job gets completed before "Coroutine scope is over"
    // E.g delay(2000)
    println("Coroutine scope is over")
}

Hope this makes sense :)

like image 137
Nicola Gallazzi Avatar answered Oct 28 '25 02:10

Nicola Gallazzi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!