Coroutines in Kotlin

Tanushree
GDSC, IIIT Allahabad
4 min readOct 21, 2021

In this article, we will be discussing the use of Coroutines in Kotlin by responding to the three must-answer questions: What? Why? How?

What are coroutines?

A coroutine is an instance of suspendable computation. It is conceptually similar to a thread, in the sense that it takes a block of code to run that works concurrently with the rest of the code. However, a coroutine is not bound to any particular thread. It may suspend its execution in one thread and resume in another one.

We have to add the following dependencies for implementing coroutines :

dependencies {...implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:x.x.x"implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:x.x.x"}

Why use coroutines when we already have well-established libraries like RxJava or Reactor on JVM?

We have many options for performing asynchronous operations like multithreading, using callbacks, etc. but Kotlin Coroutines offer much more than that.

1. Kotlin coroutines can be used across all Kotlin platforms (like JVM, JS, iOS, and in the common modules as well).

2. They do not change the code structure drastically. We can use most Kotlin coroutines capabilities nearly effortlessly (which we cannot say about RxJava or callbacks). This makes them beginner-friendly.

3. Coroutines can be thought of as lightweight threads.

You may test this by running the following code:

import kotlinx.coroutines.*// sample start
fun main()=run blocking {
repeat(100_000){
//launch a lot of coroutines
launch{
delay(5000L)
print(“.”)
}
}
}
// sample end

It launches 100K coroutines and, after 5 seconds, each coroutine prints a dot.

Now, try that with threads (remove ‘runBlocking’, replace ‘launch’ with ‘thread’, and replace ‘delay’ with ‘Thread.sleep’).

What would happen? (Most likely your code will produce some sort of out-of-memory error.)

How coroutines is a better alternative for managing asynchronous tasks?

In Android, coroutines are a great solution to two problems :

1. Long-running tasks are tasks that take too long to block the main thread.

For example, fetching a webpage or interacting with an API both involve making a network request, reading data from databases, etc.

2. Main Safety allows us to ensure that any suspend function can be called from the main thread.

For example, network requests, reading or writing from the database, or even iterating over large lists, etc

Let’s dive into each to see how coroutines help us structure code in a cleaner way!

Long-running tasks with Coroutines :

Before getting into any code, let’s discuss the two additional operations used in functions with coroutines.

· suspend- pause the execution of the current coroutine, saving all local variables.

· resume- continue a suspended coroutine from the place it was paused.

Sample code :

// Dispatchers.Mainsuspend fun fetch(){    // Dispatchers.Main    val result = get("developer.android.com")    // Dispatchers.Main    show(result)}suspend fun get(url: String) = withContext(Dispatchers.IO)

In the example above, “get” will suspend the coroutine before it starts the network request. When the network request is completed, it simply resumes the coroutine it suspended instead of calling a callback to notify the main thread.

Note:

We can suspend functions only from other suspend functions, or by using a coroutine builder like a launch to start a new coroutine.

Main Safety with Coroutines :

Well-written suspend functions are always safe to call from the main thread.

When a function works too slow for the main thread main-safe, we can make coroutines perform either the “Default” or “IO” dispatcher.

Coroutine dispatcher determines what thread or threads the corresponding coroutine uses for its execution. The coroutine dispatcher can confine coroutine execution to a specific thread, dispatch it to a thread pool, or let it run unconfined.

There are majorly 3 types of dispatchers:

· Main Dispatcher: It starts the coroutine in the main thread. It is mostly used when we need to perform the UI operations within the coroutine

· IO Dispatcher: It starts the coroutine in the IO thread, it is used to perform all the data operations such as networking, reading, or writing from the database, reading, or writing to the files.

· Default Dispatcher: It starts the coroutine in the Default Thread, used when coroutines are launched in GlobalScope is represented by Dispatchers.

In this article, we have got a glimpse of the background of coroutines.

You may dive deep into the topic through the additional resources provided in the link below:

Additional resources for Kotlin coroutines and flow (android.com)

Hope this article was worth reading !!

Thank You!

--

--