What is a Kotlin coroutine, and how does it differ from a thread?
answer
- Suspendable resumable computation, user-space
- Thread = heavy OS resource; coroutine = heap object
- Suspend frees the thread, block holds it
- delay vs Thread.sleep
- Many coroutines multiplex over few threads
basics
~10 sA coroutine is a lightweight task that can pause and resume. Unlike a thread, it does not block an OS thread while waiting, so you can run very many of them at once cheaply.
solid answer
~40 sA coroutine is a unit of suspendable computation managed in user space by the kotlinx.coroutines library, not by the OS. A thread is a heavy OS resource (megabytes of stack, scheduled by the kernel); a coroutine is just an object on the heap. When a coroutine hits a suspension point (a call to a `suspend` function that actually suspends, like `delay`), it gives up its thread instead of blocking it, and resumes later — possibly on a different thread. This means thousands or millions of coroutines can multiplex over a small thread pool. Coroutines run inside a `CoroutineScope`, are launched with builders like `launch`/`async`, and are dispatched onto threads by a `CoroutineDispatcher`. The slogan is "coroutines are like lightweight threads" — concurrency without one-thread-per-task cost.
code
kotlin · 10 linesimport kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
delay(500) // suspends; thread is reused meanwhile
println("resumed on ${Thread.currentThread().name}")
}
println("launched, not blocked")
job.join()
}go deeper
Can state a coroutine is a lightweight, pausable task and that it doesn't block a thread while waiting.
Explains user-space multiplexing over a thread pool and the suspend-vs-block distinction with delay vs Thread.sleep.
Frames it as library + compiler support, ties lifetime to scope/dispatcher, and reasons about memory/scheduling cost.
Discusses when coroutines genuinely beat threads vs not (CPU-bound work), and the system-design implications of cheap concurrency.
## What a coroutine is A **coroutine** is a computation that can be **suspended** (paused) and later **resumed**, without blocking the underlying thread it was running on. It is implemented entirely as a library (`kotlinx.coroutines`) plus a small amount of compiler support — there is no special OS or JVM primitive behind it. Think of it as a resumable function: when it needs to wait for something (a network call, a timer, another coroutine), it stores its state, returns the thread to the pool, and is scheduled to continue later from exactly where it left off. ## How it differs from a thread - **Thread**: an OS-managed execution context. It has a large stack (often ~0.5–1 MB), is scheduled preemptively by the kernel, and blocking it (e.g. `Thread.sleep`) wastes that whole resource while it waits. - **Coroutine**: a plain heap object managed in **user space**. Suspending is cooperative, not preemptive. Many coroutines share a few threads. ```kotlin import kotlinx.coroutines.* fun main() = runBlocking { // 100k coroutines — fine. 100k threads — would crash. repeat(100_000) { launch { delay(1000) // suspends, does NOT block a thread print(".") } } } ``` `delay(1000)` is a **suspending** function: it parks the coroutine and frees the thread for 1 second, unlike `Thread.sleep(1000)` which holds the thread hostage. ## Key vocabulary - **Suspension point**: a place where a coroutine may pause — only inside `suspend` functions. - **CoroutineScope**: defines a coroutine's lifetime and tracks its children. - **Coroutine builder**: `launch`, `async`, `runBlocking` — functions that actually start a coroutine. - **Dispatcher** (`CoroutineDispatcher`): decides which thread(s) the coroutine runs on (e.g. `Dispatchers.Default`, `Dispatchers.IO`). ## Why this matters Because suspension frees the thread instead of blocking it, you get high concurrency (lots of waiting tasks) at very low memory and scheduling cost — the core reason coroutines exist.
- Does each coroutine own its own thread?No. Coroutines are multiplexed over a (usually small) pool of threads by a dispatcher; a single thread runs many coroutines, and one coroutine may resume on a different thread than it started on.
- Is suspending the same as blocking?No. Blocking holds the thread idle; suspending releases the thread so other coroutines can use it, then resumes later.
Threads are dedicated phone lines; coroutines are call-waiting on a few shared lines — when one call pauses, another uses the line.
saying these in an interview costs you the question
- Says a coroutine is just a thread with another name
- Claims each coroutine has its own OS thread
- Confuses suspend with block / uses Thread.sleep inside coroutines
- Thinks the JVM has native coroutine support rather than a library + compiler