Kotlin Suspend Function: runBlocking and coroutineScope

Home » Kotlin » Kotlin Suspend Function: runBlocking and coroutineScope

We have learned the basic idea of Coroutines in the previous lesson. In this tutorial, we will explore Kotlin’s suspend functions and understand how the ‘suspend’ modifier works. Let’s dive into Kotlin’s suspending function features and usage. Let’s start with a simple example of Kotlin suspend function.

Kotlin Suspend Function: runBlocking and coroutineScope

Consider the following example:

package coroutines

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    launch {
        delay(1000L)
        println("Hello Jack!")
    }
    println("Welcome")
}

Welcome
Hello Jack!

How to move the launch block content to a new function?

fun content(){
    delay(1000L)
    println("Hello Jack!")
}

Why this happened?

Here delay() is a Suspend function. It should be called only from a coroutine or another suspend function. Let’s rewrite the code with suspend prefix.

suspend fun content(){
    delay(1000L)
    println("Hello Jack!")
}

Using Kotlin suspend function

Updated Program

package coroutines

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    launch {
        content()
        println("Hello Jack!")
    }
    println("Welcome")
}
suspend fun content(){
    delay(1000L)
    println("Hello Jack!")
}
Welcome
Hello Jack!
Hello Jack!

When you apply the “Extract function” refactoring to this code, you’ll create a new function that includes the suspend modifier. This marks your initial experience with a suspending function. Suspending functions can be employed within coroutines.

Kotlin Coroutine Scope Builders

In addition to the coroutine scope offered by various builders, you have the option to define your custom scope using the coroutineScope builder. It creates a coroutine scope and does not complete until all launched children complete.

The runBlocking and coroutineScope builders may appear similar as they both wait for their respective bodies and all the child coroutines within them to finish execution.

What is the difference between runBlocking and coroutineScope?

The main difference is that runBlocking makes the current thread wait. In contrast, coroutineScope simply pauses (suspends), allowing the underlying thread to be used for other tasks. Remember, runBlocking is a regular function and coroutineScope is a suspending function.

We can use coroutineScope from any suspending function.

Kotlin coroutineScope Example

import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    content()
}
suspend fun content() = coroutineScope{
    launch {
        delay(1000L)
        println("Hello Jack!")
    }
    println("Welcome")
}
Welcome
Hello Jack!

Concurrency with Kotlin’s coroutineScope [Example]

import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {

    taskToComplete()
    println("Hey I am done!")

}
// Concurrently executes both sections
suspend fun taskToComplete () = coroutineScope {
    launch {
        delay(2500L)
        for (i in 0..<10 step 1) println(i)
    }
    launch {
        delay(1000L)
        for(i in 0..<10 step 1 ) println(i)
    }
    println("Hey I'm starting!")
}
Hey I'm starting!
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
Hey I am done!

Both pieces of code inside launch { … } blocks execute concurrently.

In the taskToComplete function, the coroutineScope only completes once both actions have finished. As a result, taskToComplete returns and allows the “Hey I am done!” string to be printed only after this completion.

In conclusion, Kotlin’s suspend functions are a powerful tool for writing asynchronous and non-blocking code in a concise and readable manner. They allow us to work with coroutines, which simplify complex asynchronous operations and make it easier to manage concurrency. By using the Kotlin suspend modifier, we can create functions that seamlessly integrate with coroutines, enabling us to write efficient and responsive applications.

You may also like...