Coroutine in Kotlin is a feature that allows us to implement applications where the processing of some application tasks needs to wait for the result of another task, allowing us to delay or cancel running tasks. Similar to multithreading in Java, coroutine also helps us to run many different tasks at the same time. In this tutorial, I will introduce you to the basics of coroutine and how to use it in Kotlin applications.
First, I will create a new Kotlin Gradle project for example, as follows:
The first point you need to know is that to use coroutine in Kotlin applications, you need to declare a dependency for your project as kotlinx-coroutines-core as follows:
1 |
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0") |
To use coroutine in Kotlin applications, we can declare tasks to run asynchronously inside the block of runBlocking() or coroutineScope() methods.
The similarity between the runBlocking() and coroutineScope() methods is that they both wait for the tasks defined within them to be completed. The difference between these two methods is that runBlocking() will block the running thread until the task segments inside this method are finished executing, while with the coroutineScope() method, when we pause the running tasks. execute in a coroutine, the thread that the coroutine is using to execute tasks will be released so that thread can be used for other tasks.
For example, I can use the runBlocking() method as follows:
1 2 3 4 5 6 7 |
package com.huongdankotlin.coroutines import kotlinx.coroutines.runBlocking fun main() { runBlocking { } } |
Inside the runBlocking() method, we can create a new coroutine using the launch() method as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdankotlin.coroutines import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking fun main() { runBlocking { launch { delay(1000L) println("From Huong Dan Kotlin!") } println("Hello") } } |
All code inside the runBlocking() method will be interpreted as being in the CoroutineScope.
The code inside the launch() method will run at the same time as the code outside. Because I delay 1s using delay() method, the code after this delay() method will run after 1s. And so, when you run this application, you will see the following results:
As you can see, the word “Hello” was printed first, then 1 second, the words “From Huong Dan Kotlin!” was actually printed.
If you add the code after the block of the runBlocking() method and the code to display the Thread that the code is using to run, for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.huongdankotlin.kotlincoroutine import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking fun main() { runBlocking { launch { delay(1000L) println("From Huong Dan Kotlin!" + " Thread: " + Thread.currentThread().name) } println("Hello" + " Thread: " + Thread.currentThread().name) } println("Done" + " Thread: " + Thread.currentThread().name) } |
When running the example again, you will see that the code will be executed after the code in the runBlocking() method is executed.
Result:
The thread that the runBlocking() method uses is always “main”.
If you replace the runBlocking() method with the coroutineScope() method, you will see that the IDE tells us that we need to declare the suspend keyword for the method that is defining the coroutineScope() method:
This is also another difference between the two methods runBlocking() and coroutineScope()! The runBlocking() method is a normal method and coroutineScope() is the suspend method. We have to declare suspend methods using coroutineScope() method with suspend modifier.
After declaring the suspend modifier:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.huongdankotlin.kotlincoroutine import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch suspend fun main() { coroutineScope { launch { delay(1000L) println("From Huong Dan Kotlin!" + " Thread: " + Thread.currentThread().name) } println("Hello" + " Thread: " + Thread.currentThread().name) } println("Done" + " Thread: " + Thread.currentThread().name) } |
Run the application again, you will see, after a delay of 1s, the “main” thread which is used to run the application, is released. When resume, our application uses another thread to run as follows:
With coroutine in Kotlin, the tasks in the application will share threads with each other to complete. When a task is paused, it will release the thread for another task to run and vice versa, reducing the number of threads needed for the application to run. Save those resources!