Asynchronous Programming with Kotlin

- 3 mins
Kotlin Couroutines
Banner from kotlin blog


Kotlin coroutines are a way of doing “asynchronous or non-blocking programming”, but what does it mean to be “asynchronous” and “non-blocking”?

Asynchrony, Concurrency, and Parrallelism

To understand Asynchrony, let’s define it along with other terms used in the same context: Concurrency and Parallelism:

Asynchrony

A simple definition of asynchrony is the following:

“Asynchrony, in computer programming, refers to the occurrence of events independent of the main program flow and ways to deal with such events”
Wikipedia

Asynchrony is a programming model where a program starts some tasks, without waiting/blocking for the results of the tasks. The program continues his work until receiving a signal that the results are available.

Concurrency

In programming, concurrency is the composition of independently executing processes (…), [and] dealing with lots of things at once (…).
Rob Pike

Concurrency is about composition: handling multiple tasks being in progress in the same time, but not necessarily simultaneously or with a specific order.

Parallelism

Parallel computing is a type of computation in which many calculations or the execution of processes are carried out simultaneously
Wikipedia

Parallelism, often mistakenly used for concurrency, is about simultaneous execution of multiple tasks.

In programming, (…) parallelism is the simultaneous execution of (possibly related) computations. , [and] doing lots of things at once (…).
Rob Pike

The problematic

Now that we have defined asynchrony, what is the problem we are trying to solve ? Let’s consider a simple web-application that:

The picture below shows the application might work in the single-thread mode:

Single-thread request handling

This only works for a single request, when the working thread is busy handling a request, it won’t be able to respond to another request in the same time!

Thread by request

A solution might be to have a thread for each request! however, thread creation is expensive and this approach has a limit: the number of thread OS can manage concurrently!

Thread Pool

What about using thread pools? A limit here is once all the threads are busy, each new request will have to wait until a thread is available.

Yield and Continue

If a thread is doing nothing but waiting for an I/O operation (file or network), why not just to re-use it? for this to work, we need each request to yield the thread to another request instead of keeping the thread and waiting, then continue later when the waiting is done.

Coroutine Yield and Continue handling

Each function should split into chunks, release the thread after running a chunk, and continue the next chunk once the result it needs is ready. The functions are cooperating to use thread effectively and thus approach is called cooperative or non-preemptive multitasking. This is exactly what coroutines are about!

For further understanding, please read this excellent article and check the sources section below.

Reactive Streams and Coroutines

Reactive streams and Kotlin coroutines are often being compared. The following citation is an excellent answer to this comparison:

(…) RxKotlin does not use coroutines yet; the reason is quite simple–both coroutines and Schedulers in RxKotlin share nearly the same internal architecture.
Reactive Programming in Kotlin

In other terms, coroutines and Rx are simply two different layers of abstraction. However, in the near future, Kotlin Flows could be a solution to this dilemma.


Sources

Mouaad Aallam

Mouaad Aallam

Software Engineer

rss facebook twitter bsky github youtube mail spotify instagram linkedin google pinterest medium vimeo mastodon gitlab docker