Kotlin Coroutined

Shelby Cohen
Apr 1 · 4 min read

Bored in quarantine? It’s the perfect time to learn about Kotlin Coroutines 😅

Image for post
Image for post
ahsensaeed.com

What are Coroutines?

Put simply, Coroutines allow the execution of a program to be suspended or paused and then resumed. While many different languages have implementations for coroutines, today I am going to talk about Kotlin. Kotlin Coroutines are used for asynchronous or non-blocking programming. They can be used in desktop, server-side, and mobile applications. Kotlin has support for coroutines at the language level to enable other libraries to utilize them in more complex ways.

In a previous post of mine about Reactive Programming, I compared two popular reactive libraries: Project Reactor and Kotlin Flow. The combination of Kotlin language features (coroutines) and a library (Kotlin Flow) enables a powerful abstraction with a simple design. In this article you will learn a few different ways to start a coroutine and some basic rules to follow when using them.

To use coroutines in a Kotlin project, we have to add the kotlinx.coroutines version to our dependencies as follows:

Add implementation org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.4 to your gradle file
Add implementation org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.4 to your gradle file

Add Bintray JCenter as a repository and then you are ready to start coding!

For repositories use jcenter
For repositories use jcenter

How do you start a coroutine?

Starting out with a top-level coroutine, we can use GlobalScope.launch { }. This is light-weight, but it still consumes memory resources when it runs. While GlobalScope is great to use in the early stages of coroutines, there are other techniques that are more structured to handle more complex cases. The following is an example of using GlobalScope.launch { } for a simple action.

main function using global scope launch to start a coroutine
main function using global scope launch to start a coroutine
Prints: Start Hello Stop

Something that has stumped me before is using functions for coroutines in the wrong places. For example, if we move the function delay() outside of launch { } we will get a compiler error. We can only call suspend functions (function signature with the word suspend in front of fun) from a coroutine or another suspend function. We need to make sure we are inside a coroutine. We can fix this in a few different ways but the most idiomatic way is to use runBlocking to wrap the execution of the whole function. Wrapping it in runBlocking { } will start a coroutine and wait until it is complete.

main using run blocking
main using run blocking
Prints: Start Stop Hello

Another difference between this and the first example is that we are no longer using GlobalScope. The launch { } above is launching a new coroutine in the scope of runBlocking { }. Every coroutine builder adds an instance of CoroutineScope to the scope of its code block and in the case of runBlocking it won’t complete until all the coroutines launched in its scope are complete.

Also important to note that you can use runBlocking to help with your unit tests!

Unit tests using run blocking
Unit tests using run blocking

launch does not return a result or value to the caller from your coroutine. In order to execute a coroutine that returns a result, you would instead use async { }. The value returned will be an instance of Deferred<T> which has a function called await(), used to return the result of the coroutine.

The Kotlin documentation talks a lot about how coroutines are cheaper than threads. We can actually create 1 million coroutines in less than a second. The following uses async { } to run coroutines in parallel. Even if we add a delay() before n in the async block it will still complete quickly due to the parallelism.

Image for post
Image for post
Prints: 500000500000

We need to wrap the function in runBlocking in order to use .await() outside of the async block. Additionally, if we want to move the workload (anything that is inside the async block) to its own method we will have to use the suspend modifier for that function. The reason is because coroutines can suspend without blocking a thread. Marking functions that may suspend explicitly in the code allows the compiler to know how to handle it.

What’s next?

I hope that this has helped you learn the beginning steps for using Kotlin Coroutines! All the code examples in this article are variations from the KotlinLang docs, so I highly recommend using the resources you can find there, such as Coroutines Guide, Basics, and Your first coroutine with Kotlin.

Some other resources that may help Android developers get started are Improve app performance with Kotlin coroutines and Using Kotlin Coroutines in your Android App. Comment any other resources you have used!

Intuit Engineering

Thoughts from Intuit on tech, data, design, and the culture…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store