4

I have been working with coroutines for few weeks and sometimes its tough to understand the real working difference between thread concurrency and coroutine concurrency.

How suspend functions works internally ? How is continuation block helping in resuming the computation after suspension. How is sequential computation of the line of code inside coroutine not blocking the thread ? and how is it better than thread concurrency ?

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
Anup Lal
  • 59
  • 1
  • 12

2 Answers2

6

How suspend functions works internally?

Briefly, on the Java platform a suspend fun compiles into bytecode that is dramatically different from a plain function. It receives a hidden extra parameter (the continuation), creates its own continuation object, and the entire body of the function is implemented (approximately) as a big switch statement that allows the function to jump into the middle of the body when resuming.

When a suspend fun suspends, the underlying Java method actually returns. The return value is a special COROUTINE_SUSPENDED singleton object which the framework knows how to interpret. It is the responsibility of the suspend fun itself to save the continuation object where it will be accessible when the result of the function is ready.

The official documentation has a good in-depth description of these details.

How is continuation block helping in resuming the computation after suspension.

This is related to what I said above, that the suspend fun itself is responsible for ensuring it gets resumed later on. It must do that inside the block provided by the function suspendCoroutineOrReturn. User code doesn't call it directly, but the more high-level analogs suspendCoroutine and suspendCancellableCoroutine. These take over the concern of resuming the coroutine on the appropriate thread and the developer is responsible only for ensuring that continuation.resume() is called with the result when it becomes available. This typically happens in a callback you pass to an async call.

You can study this answer that tries to explain the suspend-resume mechanism in a self-contained example.

How is sequential computation of the line of code inside coroutine not blocking the thread?

Because it actually compiles into returning from the function and later on resuming by jumping into the middle of the function body.

and how is it better than thread concurrency?

Native threads are heavyweight resources that take time to create and destroy. Coroutines are much lighter-weight and consequently you can start many more of them, and more quickly.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • Marko related to your last point related to the performance with thread i would to like have more clarity on this, so you mean to say that the threads have context switching which coroutine does not ? – Anup Lal Dec 07 '19 at 06:00
  • "Context switching" is something the OS does and it involves entering the kernel mode (this is an expensive operation). Then the OS finds another thread to resume, sets up its stack and register contents, and switches back to the user mode (another expensive operation). None of this happens when a coroutine suspends and the dispatcher resumes another one, it's just Java method invocations. – Marko Topolnik Dec 07 '19 at 09:10
4

The internal workings are explained in the original design document https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md which has a section on "Implementation Details".

Roman Elizarov
  • 27,053
  • 12
  • 64
  • 60