A Coroutine is a lightweight thread of execution that can be suspended and resumed later. There are already many articles or topics covering this but this post is different, it is simple and can let you get start more easily. It will cover the following parts:
- Introduction to Coroutine in Kotlin (This article)
- Non-blocking in Kotlin Coroutines
- Start and Suspend a Coroutine in Kotlin (Incoming this week)
Overview
Like many other programming languages such as JS, Python, Coroutine is a feature provided by Kotlin that enable us to perform long and time consuming task. In short:
In Kotlin, Coroutines are a way to write asynchronous, non-blocking code in a more sequential, easy-to-read way.
In fact, nothing new techiques here. We can treat Kotlin Coroutine as a framework/library that encapsulates the some common usages while dealing with asynchronization.
Simple examples of using coroutines in Kotlin
To use coroutines in Kotlin, you need to include the kotlinx-coroutines-core
library in your project. In your app gradle file (there is only one gradle file under IntelliJ project, or choose the gradle file for app if it is Android project), add the following line:
dependencies {
testImplementation(kotlin("test-junit"))
implementation(kotlin("stdlib-jdk8"))
// add coroutine dependency
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2")
}
Then, you can use the suspend
keyword to mark a function as a coroutine and use the launch
or async
functions to start a coroutine.
1. Use launch
to create coroutines
Here is an example of using a coroutine to perform a long-running task in the background:
import kotlinx.coroutines.*
fun main() {
// Start a coroutine using the launch function
val job = GlobalScope.launch {
// Perform a long-running task in the background
delay(1000L)
println("Hello, world!")
}
// Wait for the coroutine to finish
runBlocking {
job.join()
}
}
https://gist.github.com/arkilis/6cdd2d4ad1d30e5852cd1a46210833e0
In this example, the launch
function starts a coroutine in the background and returns a Job
object that you can use to wait for the coroutine to finish. The delay
function is a suspending function that suspends the coroutine for a given amount of time.
2. Use async
to create coroutines
Here is an example of using coroutines in Kotlin to perform multiple tasks in parallel and then wait for all of them to finish:
import kotlinx.coroutines.*
fun main() {
// Start two coroutines using the async function
val job1 = GlobalScope.async {
// Perform a long-running task in the background
delay(1000L)
println("Task 1")
}
val job2 = GlobalScope.async {
// Perform a different long-running task in the background
delay(2000L)
println("Task 2")
}
// Wait for both coroutines to finish
runBlocking {
job1.await()
job2.await()
}
}
In this example, the async
function is used to start two coroutines in the background. The await
function is used to wait for the coroutines to finish. Because the coroutines are running concurrently, the tasks are performed in parallel and the output is printed in the order that the tasks complete.
The difference between launch and async to start a coroutine
Both of them are commonly used to start a coroutine. The main difference between the two is that launch
returns a Job (a non-blocking cancellable future) and does not return a result, while async
returns a Deferred (a non-blocking cancellable future with a result) that can be used to obtain the result of the coroutine. Considering the difference, when should use the launch and async to create coroutines:
- When you use
launch
function, the coroutine will run in the background and the function call will return immediately. It is used when the result of the coroutine is not needed. - When you use
async
function, the coroutine will also run in the background and the function call will return immediately, but it will return aDeferred
object on which you can call .await() function to get the result of the coroutine. It is used when the result of the coroutine is needed. For example:
val result = GlobalScope.async {
return@async URL("https://api.example.com/data").readText()
}
val data = result.await()
println(data)
// output: {"fact":"A group of cats is called a \u201cclowder.\u201d","length":38}
Summary
Coroutines can make it easier to write concurrent and asynchronous code in Kotlin, it is not some cutting-edge technology but a wrapper of threads provided by Kotlin.
What is more from here? As we know Coroutine is a big topic and few wores can explain all of it. This is the first article of the Coroutine series. If you interested, please subscribe for more coming posts on this:
- Non-blocking in Kotlin Coroutines
- Start and Suspend a Coroutine in Kotlin (Incoming this week)
To learn more about coroutines and how to use them, you can read the official documentation at https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html.