What phenomenon are coroutines? These are basically lightweight threads providing better use of the apps they are operating on. Furthermore, there’s no need to manually control the threads performing them.

The developer stays away from the lifespan of threads as new abstractions added by coroutines ensure context switching between tasks. Thus, the operational time of the threads is used more rationally.

It doesn’t take long to finally get a result from a notoriously sluggish input/output task. On the contrary, it keeps on processing tasks issued by other coroutines.

A developer’s typical work day involves code building and each one takes around 3-5 minutes. Meanwhile, they check emails and Twitter, do some stretching, or simply chillax, you name it. This is where coroutines step in. You get the most out of your time while waiting for the build to complete.

Moving forward, the idea of Kotlin coroutines is not brand new. A lot of programming languages make use of them, such as Go (goroutines), Erlang, and Java (Project Loom).

Installation Stage

Only a few keywords are integrated with the Kotlin library. This is not a big deal. You simply add a dependency on kotlinx-coroutines-core in order to enter coroutines. That wouldn’t take much effort. Check it for yourself.

Gradle:

dependencies {
   implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}

Maven:

<dependencies>
 <dependency>
     <groupId>org.jetbrains.kotlinx</groupId>
     <artifactId>kotlinx-coroutines-core</artifactId>
     <version>1.6.4</version>
 </dependency>
</dependencies>

As long as the library gets updated, variations alter.

An Easy Coroutine

Let’s consider a limited-scope example below to get familiar with coroutines. Keep in mind that most of the upsides aren’t shown by this pattern. The more you learn about coroutines, the better you realize their benefits.

First, check this out:

fun main() = runBlocking {
   launch {
     delay(2000)
     println("and it worked for me!")
   }
   print("My first coroutine, ")
}

Here a code activates a coroutine with a delay before proceeding to the next step - printing out. The laconic example contains a couple of functions to hold your attention. Take a close look at them.

Clarification of the terms

A few words are to be explained.

Suspending Function

What kind of function is that?

Such a method has already been shown in the example above – delay. The compositions of delay are:

public suspend fun delay(timeMillis: Long) {
  if (timeMillis <= 0) return // don't delay
    return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->
      cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont)
 }
}

Luckily, Kotlin language contains the suspend keyword. What is the point of it?

You are aware that the functions that suspend through their execution at a point are marked as suspend. Honestly, it takes a thorough getting into details to provide a comprehensive explanation on the matter. Otherwise, figuring out when functions suspend may be really tangled.

When do you annotate the function with suspend? Just go by the book, if a function is prefaced with suspend, and the calling point is outside the coroutine.

Compare a calling point outside a coroutine:

suspend fun printAfterDelay() {
  delay(2000)
  println("and it work!")
}

To a calling point inside a coroutine on the other hand:

fun CoroutineScope.printAfterDelay() = launch {
  delay(2000)
  println("and it work!")
}

By the way, have you noticed that both examples are insignificant code refactoring of the original one?

The compiler will come in handy in various situations, this is the exact benefit of a keyword. Thus, compiling the below:

fun printAfterDelay() {
  delay(2000)
  println("and it work!")
}

Will eventually result in such an error:

Suspend function 'delay' should be called only from a coroutine or 
another suspend function

Note that this is an instructive explanation before you technically advance into action and become an expert in coding.

Summary

Kotlin coroutines are considered lightweight threads, a means of providing program multithreading in the sense that they can be implemented without the use of context switching mechanisms by the operating system.

They split and output their underlying resources when a certain coroutine hits a suspension point. This enables efficient usage of application resources since threads don’t have to be blocked during long-term tasks.

Wrapping up, we had a look at a simple pattern of an easy coroutine and a suspending function. Lastly, we touched on the suspend keyword and how to operate it.

The given examples don’t illustrate the real value of using coroutines. The article describes only the basics. Keep an eye out for further in-depth guidance on the subject.