Kotlin Coroutines: Coroutines are NOT light weight threads.

Abhishek Kumar
4 min readJan 30, 2022

--

Since you are here I am assuming you are familiar with the concept of asynchronous programming and multi-threading in some form or another. On the off chance that you aren’t, you are probably drunk browsing. Go to bed.

Introduction

“Coroutines are light weight threads” — How many times have you come across this phrase? This definition is simply absurd and could not be farther from the real meaning.

The confusion exists because of a seemingly innocent statement in the documentation:

Coroutines can be thought of as light-weight threads, but there is a number of important differences that make their real-life usage very different from threads.

It says “can be thought of as light weight threads”, and not “are light weight threads”. I have seen people get confused about coroutines just because they always think of them as threads. Let’s fix this by understanding the core difference.

What is a thread in its most basic form? It is a sequential flow of control in a program. The word “sequential” is of essence here. Check out these functions:

fun firstFunction() {
//Code snippet 1
secondFunction()
//Code snippet 2
}
fun secondFunction() {
//Code snippet 3
}

If a thread calls firstFunction then the code will execute in the following order:

  1. Code snippet 1
  2. Code snippet 3
  3. Code snippet 2

These 3 code snippets will always run on the thread that calls firstFunction and the order of execution of these 3 code snippets within a thread will always be same. Another way to look at this is that if a function execution starts on a thread, this thread will not be free until this function has returned.

This can be wasteful. Especially if we are talking about the main thread. What if code snippets 1 and 2 were simple, “quickly executable” tasks but code snippet 3 involved resource consuming IO operations? If code snippet 2 and 3 are independent of each other, is it wise to keep code snippet 2 waiting until code snippet 3 finishes execution? Would it not be more efficient if somehow our resource intensive code snippet 3 ran on a separate thread? This way code snippet 1 and 2 run on one thread, but 3 runs on a different thread parallelly. This is what coroutines is all about. “Co” means together and “routines” is another name for functions. It’s right there in the name folks.

But why did we need coroutines? In our example above why do we need our thread to be free asap? It’s not the main thread, it’s just a worker thread. Then what is the problem? The problem is that in a professional application, there are numerous parallel tasks that need to be executed. Now you might argue — Why not keep creating new Threads for every parallel computation? Because thread creation is a resource intensive operation. Also, a Thread is after all an object that resides in the memory. Each Java thread has its own stack which is typically 1 MB. (64k is the least stack space allowed in JVM). So you cannot keep creating new threads when and where you please. Thread pools kinda solved this problem. As the name suggests, a thread pool is a collection of reusable threads. When ever the app needs a new thread, it simply takes a free thread from the pool, performs execution after which the thread is returned to the pool. But this still might be problematic when there are too many parallel tasks to execute. Coroutines solve this problem. You can have as many coroutines in your application as you like (each coroutine is typically few dozen bytes). Coroutines stick to a thread until a suspension point(we will cover this in future articles) is reached at which point it leaves the thread and frees it up allowing it to execute some other coroutine if it is waiting. This way with limited number of threads and consequently less memory usage much more concurrent work can be done.

This is an over-simplification of a seemingly complex subject. But the purpose of this article was to clearly highlight the difference between coroutines and threads and why coroutines are not light weight threads. In future articles we will take a deep dive into Coroutines, how to launch them, suspend functions, CoroutineScope, CoroutineContext, and more. Tons of stuff coming up.

Drunk guy, if you’re still reading go to bed man!

Peace!

--

--

Abhishek Kumar
Abhishek Kumar

Written by Abhishek Kumar

I'm a Tech enthusiast, currently working with VMware. When I'm not turning coffee into code, I enjoy writing, cinematography and reading.

Responses (3)