Coroutines Intro

Kotlin is a modern, concise language whose coroutines let you write asynchronous, non-blocking code that reads like ordinary sequential code — no callback pyramids required.

Learn Coroutines Intro in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

By the end of this lesson you'll write suspend functions, launch coroutines, and run work concurrently with async / await .

What You'll Learn in This Lesson

1️⃣ suspend Functions and runBlocking

A suspend function can pause at suspension points (like delay ) without blocking its thread. You can only call one from another suspend function or a coroutine builder. runBlocking bridges ordinary code into the coroutine world — common in main and tests.

The code reads top-to-bottom like normal sequential logic, yet the delay doesn't freeze the thread — that's the magic of coroutines.

2️⃣ launch, async, and Concurrency

launch starts a fire-and-forget coroutine and returns a Job . async starts one that produces a result as a Deferred , which you read with await() . Two async calls run concurrently .

Both loads each take a second, but because they ran concurrently the total wait is about one second, not two. That's how coroutines turn sequential waits into parallel ones.

Your turn. Replace the TODO , then run and compare.

Run two suspend functions concurrently with async and combine their results.

📋 Quick Reference — Coroutines

Practice quiz

What does the 'suspend' keyword mark a function as?

  • A function that can pause at suspension points without blocking its thread
  • A function that always runs on a new thread
  • A function that cannot be cancelled
  • A function that blocks the main thread

Answer: A function that can pause at suspension points without blocking its thread. suspend marks a function that may pause and resume later without blocking the underlying thread.

Where can a suspend function be called from?

  • Any ordinary function
  • Only the main function
  • Another suspend function or a coroutine builder like launch/async/runBlocking
  • Only from inside a class

Answer: Another suspend function or a coroutine builder like launch/async/runBlocking. Suspend functions can only be called from another suspend function or a coroutine builder.

How does delay() differ from Thread.sleep()?

  • delay() is slower than Thread.sleep()
  • They are identical
  • delay() blocks two threads at once
  • delay() suspends the coroutine and frees the thread; Thread.sleep blocks the thread

Answer: delay() suspends the coroutine and frees the thread; Thread.sleep blocks the thread. delay suspends only the current coroutine, releasing the thread; Thread.sleep blocks the whole thread.

What does the launch coroutine builder return?

  • A Job
  • A Deferred
  • A String
  • Nothing at all

Answer: A Job. launch starts fire-and-forget work and returns a Job you can join or cancel.

What does async return?

  • A Job
  • A Deferred that you read with await()
  • A plain value immediately
  • A Thread

Answer: A Deferred that you read with await(). async returns a Deferred<T>; call await() to get the result.

What is runBlocking typically used for?

  • Cancelling all coroutines
  • Replacing the JVM thread pool
  • Bridging ordinary code into the coroutine world, e.g. in main and tests
  • Creating new threads only

Answer: Bridging ordinary code into the coroutine world, e.g. in main and tests. runBlocking bridges normal blocking code and the coroutine world.

How do you get the result out of a Deferred?

  • By calling .join()
  • By calling .await()
  • By calling .close()
  • By reading .value directly

Answer: By calling .await(). await() suspends until the Deferred's result is ready and returns it.

Starting two async blocks and then awaiting both lets the work run...

  • Sequentially, one after the other
  • On the UI thread only
  • Never, it deadlocks
  • Concurrently, so total wait is about one delay not two

Answer: Concurrently, so total wait is about one delay not two. Both async coroutines run concurrently, so two 1s tasks finish in about 1s total.

What does structured concurrency guarantee about child coroutines in a scope?

  • They are cancelled together with the scope
  • They run on separate processes
  • They never get cancelled
  • They ignore their parent scope

Answer: They are cancelled together with the scope. Children launched in a scope are cancelled together, preventing leaks by design.

Which Dispatcher is intended for network and disk work?

  • Dispatchers.Main
  • Dispatchers.Default
  • Dispatchers.IO
  • Dispatchers.Unconfined only

Answer: Dispatchers.IO. Dispatchers.IO is for blocking I/O like network and disk; Default is for CPU work.