Home » Kotlin coroutines nested launch

Kotlin coroutines nested launch

  • by
Kotlin coroutines nested launch

1. Overview

In this article, we will learn about the Kotlin coroutines nested launch.

2. Kotlin Coroutines

A coroutine is a concurrency design pattern you can use to simplify code that executes asynchronously.

It takes a block of code to run, that works concurrently with the rest of the code. However, it is not bound to any thread. It may suspend its execution in one thread and resume in another one.

Kotlin coroutines are extremely inexpensive when compared with threads. Each time when we want to start a new task asynchronously, we can create a new coroutine. To start a new coroutine, we use one of the main “coroutine builders”: launchasync, or runBlocking.

JetBrains developed the rich kotlinx.coroutines library as part of version 1.3 for coroutines.

To learn the differences between launch vs async, refer to this article.

3. Kotlin launch coroutines

The launch coroutine builder launches a new coroutine without blocking the current thread and returns a reference to the coroutine as a Job.

fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext, 
    start: CoroutineStart = CoroutineStart.DEFAULT, 
    block: suspend CoroutineScope.() -> Unit
): Job

Here is an example of the launch:

fun main()  = runBlocking() {
    println("main() : ${Thread.currentThread().name}")
    val job: Job = launch { 
                println("Launch : ${Thread.currentThread().name}")
                println("Launch :  ${Thread.currentThread().name}}")
    }
   println("main() : ${Thread.currentThread().name} ")
}

If you execute the above code, the following logs appear on the console. As you can see, the code inside the launch block executes asynchronously.

main(): main @coroutine#1 
main(): main @coroutine#1
Launch: main @coroutine#2 
Launch:  main @coroutine#2

3.3. Kotlin nested launch coroutines

You can create nested launch coroutines as below:

fun main()  = runBlocking {
    supervisorScope {
        println("main() method: ${Thread.currentThread().name}")
        val job: Job = launch { 
                    println("launch corotine: ${Thread.currentThread().name}")
                    delay(100)
                    val job2: Job = launch { 
                        println("launch 2 corotine: ${Thread.currentThread().name}")
                        delay(110)
                        println("launch 2 corotine:  ${Thread.currentThread().name}")
                        "Hello World 2"
        	    }
                    job2.join()
                    println("launch corotine:  ${Thread.currentThread().name}")
                    "Hello World"
        }
        job.join()
        println("main() method on ${Thread.currentThread().name}")
   }
}

Notice that executing the above code, prints the following logs on the console.

main() method: main @coroutine#1
launch corotine: main @coroutine#2
launch 2 corotine: main @coroutine#3
launch 2 corotine:  main @coroutine#3
launch corotine:  main @coroutine#2
main() method on main @coroutine#1

If you cancel the parent launch coroutine by invoking the cancel method on the Job, it cancels the children launch coroutine as well.

fun main()  = runBlocking {
    supervisorScope {
        println("main() method: ${Thread.currentThread().name}")
        val job: Job = launch { 
                    println("launch corotine: ${Thread.currentThread().name}")
                    delay(100)
                    val job2: Job = launch { 
                        println("launch 2 corotine: ${Thread.currentThread().name}")
                        delay(110)
                        println("launch 2 corotine:  ${Thread.currentThread().name}")
                        "Hello World 2"
        	    }
                    job2.join()
                    println("launch corotine:  ${Thread.currentThread().name}")
                    "Hello World"
        }
        job.cancel()
        println("main() method on ${Thread.currentThread().name}")
   }
}

If you execute the above code, we have canceled the parent coroutine which in turn automatically cancels the child coroutine as well.

main() method: main @coroutine#1
main() method on main @coroutine#1

By default, the execution of the launch coroutine starts immediately. However, you can also start the execution of the Launch coroutine lazily.

val job: Job = launch(Dispatchers.Default, CoroutineStart.LAZY) { 
                println("Launch: ${Thread.currentThread().name}")
                println("Launch corotine:  ${Thread.currentThread().name}")
    }

4. Conclusion

To sum up, we have learned the Kotlin coroutines nested launch methods. You can find code samples in our GitHub repository.

Leave a Reply

Your email address will not be published.