Tag: dispatcher

Kotlin Coroutines Guide – Concurrent Programming in Kotlin

Kotlin Coroutines Guide – Concurrent Programming in Kotlin

Introduction and Motivation

In this article, I’d like to share my gathered insights on Kotlin Coroutines with you and hope to give a comprehensive overview. The shown code runs with Kotlin version 1.2.40 and kotlinx.coroutines version 0.22.5.
Kotlin coroutines are definitely one of the “bigger features” as indicated by the following quote, taken from JetBrains’ blog:

We all know that blocking is bad under a high load, that polling is a no-go, and the world is becoming more and more push-based and asynchronous. Many languages (starting with C# in 2012) support asynchronous programming through dedicated language constructs such as async/await keywords. In Kotlin, we generalized this concept so that libraries can define their own versions of such constructs, and async is not a keyword, but simply a function.
This design allows for integration of different asynchronous APIs: futures/promises, callback-passing, etc. It is also general enough to express lazy generators (yield) and cover some other use cases.

To put it simply, JetBrains introduced coroutines in order to provide simple means for concurrent programming. Probably many of you have already worked with Java, its Threads and concurrency classes; I myself did this quite a lot and actually, I’m really convinced of its maturity.

Java Concurrency vs. Kotlin Coroutines

If you still catch yourself struggling with Threading and Concurrency in Java, I can recommend the book Java Concurrency in Practice to you.

Although Java’s solution is really well-engineered, it’s often difficult to utilize and (of course) very verbose. Another problem is, that Java doesn’t directly encourage non-blocking programming. You often find yourself starting threads without having in mind, that they’re very expensive and introduce blocking computations quickly (due to locks, sleeps, waits, etc.). Applying non-blocking patterns alternatively is really hard and error-prone.

Kotlin Coroutines, on the other hand, are intended to be much easier and look like sequential code by hiding the complex stuff inside library functions. Yet, they provide a way to run asynchronous code without having to block threads, which provides new possibilities for applications [1]. Instead of blocking threads, computations are being suspended.
JetBrains tends to describe coroutines as “light-weight threads”; actually they are no Thread as we know them in Java. Compared to threads, coroutines are very cheap in the creation and the overhead introduced by threads isn’t around. One reason is, that they’re not directly mapped to native threads. As you will see, coroutines are executed in Threads managed by the library.
Another important difference is “limitation”: Threads are limited because they rely on available native threads, coroutines on the other side are almost free and thousands can be started at once.

Concurrent Programming Style

Different styles of asynchronous/concurrent programming styles exist in various languages, which for example are: callback-based (JavaScript), future/promise-based (Java, JavaScript), async/await-based (C#) and so on. All these concepts can be implemented with coroutines because Kotlin doesn’t dictate any style initially. Instead, all concepts are already, or at least could in future, (be) implemented using coroutines.
As one additional benefit, as opposed to e.g. callback-based programming, coroutines promote a sequential kind of asynchronous programming, i.e. although your coroutines may execute multiple parallel computations, your code still looks sequential and therefore acquainted.

The Concept of Kotlin Coroutines

The term and concept “Coroutine” is anything but new. According to the Wikipedia article, it was created in 1958 already. Many modern programming languages provide native support: C#, Go, Python, Ruby, etc. The implementation of coroutines, also in Kotlin, is often based on so-called “Continuations”, which are “an abstract representation of the control state of a computer program”. We’ll capture that in How does it work – Implementation of Coroutines again.

Getting Started – The Basics

There’s a comprehensive tutorial available on https://kotlinlang.com that describes how a project needs to be set up in order to work with coroutines. Please have a look there or just check out my Kotlin_Examples repository on GitHub.

Kotlin Coroutines Ingredients

As already hinted, the Kotlin coroutine library provides an understandable high-level API that lets us start quickly. One new modifier we need to learn is suspend, which is used to mark a method as “suspending”.
We’ll have a look at some easy examples using APIs from kotlinx.coroutines up next. But first, let’s learn what a suspending function is.

Suspending Functions

Coroutines rely on the keyword suspend, which is a modifier used in order to mark functions as “suspending” [2], i.e. that calls to such functions may suspend at any point. These can only be called from within coroutines, which in turn need at least one suspending function to be started.

suspend fun myMethod(p: String): Boolean {

As we can see in the example above, suspending functions look like regular functions plus the additional modifier. Keep in mind, that these methods can only be called from coroutines, other attempts will lead to compilation errors.

Coroutines can be thought of as a sequence of regular and suspending functions with an optional result being available after completion.


Let’s see some concrete coroutines in action. In a first example, the basics will be shown:

The first Coroutine

fun main(args: Array<String>) = runBlocking { //(1)
    val job = launch(CommonPool) { //(2)
        val result = suspendingFunction() //(3)
    print("The result: ")
    job.join() //(4)
>> prints "The result: 5"

In this example, two functions, (1) runBlocking and (2) launch, are used, which are examples of coroutine builders. Many different builders exist, each of which starts a coroutine with different purposes: launch (fire and forget), async (promise returned), runBlocking (blocks thread) and so on.

The inner coroutine started by (2) launch does the actual work: a (3) suspending function is called which might suspend at any time, the result is printed after completion. The main thread, after starting the coroutine, prints a String before the coroutine finishes.
Coroutines started by launch return a Job immediately, which can be used for canceling the computation or waiting for completion with (4) join() as we see here. Since calling join() may suspend, we need to wrap this call into another coroutine, which can often be achieved with runBlocking. This concrete coroutine builder (1)is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests” (Quoted API). If we removed the joining of the job, the program would stop before the coroutine can print the result.

Going deeper

A more lively example is the following: Imagine, you have to send an email from your application. Requesting the recipient address and rendering the message body are two very expensive tasks, which are independent of each other though. Being smart and using Kotlin, you want to make use of coroutines, performing both tasks in parallel, of course.
This is shown here:

email example async/await
suspend fun sendEmail(r: String, msg: String): Boolean { //(6)
    println("Sent '$msg' to $r")
    return true

suspend fun getReceiverAddressFromDatabase(): String { //(4)
    return "coroutine@kotlin.org"

suspend fun sendEmailSuspending(): Boolean {
    val msg = async(CommonPool) {             //(3)
        "The message content"
    val recipient = async(CommonPool) { 
        getReceiverAddressFromDatabase()  //(5)
    println("Waiting for email data")
    val sendStatus = async(CommonPool) {
        sendEmail(recipient.await(), msg.await()) //(7)
    return sendStatus.await() //(8)

fun main(args: Array<String>) = runBlocking(CommonPool) { //(1)
    val job = launch(CommonPool) {
        sendEmailSuspending() //(2)
        println("Email sent successfully.")
    job.join() //(9)

First, like already seen in the previous example, we use a (1) launch builder inside a runBlocking builder so that we can (9) wait for the coroutine’s completion. This isn’t new and neither is the (2) call to a suspending function sendEmailSuspending.
This method uses an (3) inner coroutine for getting the message content and (4) another suspend method getReceiverAddressFromDatabase for the address. Both tasks are executed in a separate coroutine build with (5) async. Note, that the calls to delay represent a non-blocking, coroutine suspending, alternative to Thread.sleep, which is used for mocking expensive computations here.

The async Coroutine Builder

The async builder is really simple and easy in its conception. As we know from many other languages, this method returns a promise, which is strictly speaking of type Deferred in Kotlin. All terms like promise, future, deferred or delay are often used interchangeably for describing the same concept: The async method promises to compute a value which we can wait for or request at any time.

We can see the “waiting” part of Kotlin’s Deferred objects in (7), where the suspending function (6) is called with the results of both prior computations. The method await() is called on instances of Deferred which suspends until the results become available [3]. The call to sendEmail is also wrapped in an async builder, for which completion we wait in (8) before returning its result.

The CoroutineContext

One important part of the above examples is the first parameter of the builder functions, which must be an instance of CoroutineContext. This context is what’s passed to a coroutine and provides access to the current Job (remember, this is what can be used outside a coroutine for cancellation or joining) for example.
Also, the current context may be utilized for launching inner coroutines, which has the effect that the sub-coroutine’s Job is a child of its surrounding one. That provides the possibility to cancel whole hierarchies of coroutines with a single cancellation request to the parent Job.
Different kinds of Elements are part of a CoroutineContext, one of which is CoroutineDispatcher.

In all examples shown, I used CommonPool, which is such a dispatcher. It makes sure, that the coroutines are executed in a thread pool managed by the framework. Alternatively, we could have used a confined thread, specially created, or implement our own pool for example. Contexts can even be combined easily using the overloaded + operator like so:

launch(CommonPool + CoroutineName("mycoroutine")){...}

Also, note that the CommonPool is the default dispatcher and it’s therefore defined as the default argument for the coroutine builder. We could have simply written launch { ... }, async { ... } and so on.

Shared Mutable State

Maybe, while reading the previous chapters, you have had concerns about synchronization between coroutines since I didn’t show mention any of this before. I, at least, had this concern because coroutines make use of thread pools (like CommonPool) to be dispatched in and therefore could work on shared state concurrently. It’s quite evident that synchronization is just as important as we know it from other languages like Java. We can make use of acquainted strategies like thread-safe data structures, confining execution to a single thread or using locks (see Mutex for further details).
Besides the common patterns, Kotlin coroutines encourage the use of a “share by communication”-style (see QA).

Concretely, an “actor” can be shared between coroutines. They can be used by coroutines, which may send/take messages to/from it. Let’s see how this works:


actor message passing example
sealed class CounterMsg {
    object IncCounter : CounterMsg() // one-way message to increment counter
    class GetCounter(val response: SendChannel<Int>) : CounterMsg() // a request with channel for reply.

fun counterActor() = actor<CounterMsg>(CommonPool) { //(1)
    var counter = 0 //(9) actor state, not shared
    for (msg in channel) { // handle incoming messages
        when (msg) {
            is CounterMsg.IncCounter -> counter++ //(4)
            is CounterMsg.GetCounter -> msg.response.send(counter) //(3)

suspend fun getCurrentCount(counter: SendChannel<CounterMsg>): Int { //(8)
    val response = Channel<Int>() //(2)
    val receive = response.receive()
    println("Counter = $receive")
    return receive

fun main(args: Array<String>) = runBlocking<Unit> {
    val counter = counterActor()

    launch(CommonPool) { //(5)
            while(getCurrentCount(counter) < 100){
                println("sending IncCounter message")
                counter.send(CounterMsg.IncCounter) //(7)

    launch(CommonPool) { //(6)
        while ( getCurrentCount(counter) < 100) {
    counter.close() // shutdown the actor

This example shows the usage of an (1) Actor, which is a coroutine itself working on any context. The actor is holding the (9) relevant state of this sample application, which is counter. Another important feature, we haven’t considered so far, is a (2) Channel:of


Channels provide a way to transfer a stream of values, similar to what we know as BlockingQueue (enables producer-consumer pattern) in Java but without any blocking methods. Instead, send and receive are suspending functions used for providing and consuming objects from the channel, implemented with FIFO strategy, making them fair.

The actor is, by default, associated to such a channel, which can be used in other coroutines (7) for sending messages to it. In the example, the actor iterates over the stream of messages from its channel (for works with suspending calls) handling them according to their type: (4) IncCounter messages make the actor change its state by incrementing the counter while (3) GetCounter makes the actor return its counter state by sending an independent message to the GetCounter‘s SendChannel.
The first coroutine (5) in main, just for the sake of convenience, launches a task which sends (7) IncCounter messages to the actor as long as the counter is less than 100. The second (6) just waits until the counter reaches 100. Both coroutines make use of the suspending function (8) getCurrentCounter, which sends a GetCounter message to the actor and suspends by waiting on receive to return.

As we can see, the whole relevant state is confined to the specific actor coroutine. This solves the problem of shared mutable state.

More Features and Examples

If you really want to dive into coroutines and start working with it, I recommend the commonly known Kotlin documentation and especially want to suggest this fantastic guide.

How does it work – Implementation of Kotlin Coroutines

I cannot go too much into detail here because this would exceed the post’s intention. I’m planning to write a follow-up with more detailed information on implementation, considering the generated bytecode of coroutines as well, in the next weeks.
For now, let’s limit the following description to a “bird’s eye view”-ish one.

Coroutines do not rely on features of the operating system or the JVM. Instead, coroutines and suspend functions are transformed by the compiler producing a state machine capable of handling suspensions in general and passing around suspending coroutines keeping their state. This is enabled by Continuations, which are added as a parameter to each and every suspending function by the compiler; this technique is called “Continuation-passing style”.
If you can’t wait to know any details, you need to read this explanation.

Pro Tips by Roman Elizarov

I’ve talked to Roman Elizarov from JetBrains, who’s highly responsible for Kotlin coroutines and want to share the gathered information with you:

The first question I had: When am I supposed to use coroutines and are there any use cases that still require threads to be used?

A: Rule of thumb by Roman:
Coroutines are for asynchronous tasks that wait for something most of the time. Threads are for CPU-intensive tasks.

I mentioned, that the phrase “light-weight thread” sounds kind of inappropriate to me as it obscures the fact, that coroutines rely on threads since they are executed in a pool of threads. In my opinion, coroutines are rather a “task” being executed, stopped etc.

A: Roman answered, that the phrase “light-weight threads” is rather superficial, and that “coroutines are in many ways like threads from user’s standpoint.”

As a last question, I wanted to know about synchronization. If coroutines are alike threads, there must be the necessity of synchronizing shared state between different coroutines.

A: Roman told me, that known patterns of synchronization may be used, but it is recommended not to have any mutable shared state at all when we use coroutines. Instead, coroutines “encourage […​] to adopt “share by communication” style.


Kotlin Coroutines once again demonstrate Kotlin’s magnificence. As opposed to Java, Kotlin encourages a totally different style of concurrent programming, which is non-blocking and naturally doesn’t make us start huge amounts of native threads.
In Java, it’s mostly normal to just start another thread or create new pools without having in mind, that this introduces a huge overhead and can even make our application slow due to blocking code for example. Coroutines, as an alternative, are said to be “light-weight threads”, which describes the fact, that they’re not mapped to native threads and therefore don’t drag along all the risks and problems we usually have to deal with (deadlocks, starvation e.g.). As we’ve seen, with coroutines, we normally don’t have to worry about blocking threads, synchronization is much more straightforward and not even necessary ideally as long as we pursue “share by communication”.

Coroutines also enable us to work with several different kinds of concurrent programming, each of which is either available in the library already (kotlinx.coroutine) or at least could be implemented easily.
Java developers, in particular, might most likely be acquainted with submitting tasks to a thread pool and waiting for results of futures then (ExecutorService), which we easily achieve by using async/await style. Yet, it’s not just an equal replacement, but a big improvement to what we know already.
Think about your concurrent Java code, all those checked exceptions, defensive locking strategies and a lot of boilerplate code. With coroutines, it’s normal to write code sequentially by calling suspend functions, communicating with other coroutines, waiting for results, canceling coroutines and more.


Although I’m convinced that coroutines are truly fantastic, time will show whether it’s actually mature enough for highly concurrent applications. Many programmers will have to rethink and apply totally different concepts to their programs. I’m really curious about its future. As of now, Kotlin coroutines are just experimental, which means JetBrains might adjust them in upcoming releases in order to adapt feedback from the community after playing around or even adopting coroutines in productive projects.

Please don’t hesitate to get in touch, feedback’s always appreciated 🙂 Also if you like, have a look at my [Twitter](https://twitter.com/s1m0nw1) and follow if you’re interested in more Kotlin stuff 🙂 Thanks a lot.If you want to read more about Kotlin’s beautiful features I highly recommend the book Kotlin in Action and my other articles to you.



1. Non-blocking programming became more and more popular in the last time because reactive programming gained influence.
2. Actually, it’s “possibly suspending” since such a function may suspend, but doesn’t have to.
3. Keep in mind, that Java’s Future blocks a thread as soon as we call get() on it.


Simon is a software engineer based in Germany with 7 years of experience writing code for the JVM and also with JavaScript. He’s very passionate about learning new things as often as possible and a self-appointed Kotlin enthusiast.

Please follow and like this Blog 🙂