Asynchronous Programming with Coroutines

In the first part of this guide we saw how suspend functions can be used to define coroutines, i.e., computations that can be suspended, without blocking the hosting thread, and later resumed on potentially different threads. We also saw how this is achieved using two additional low-level building blocks:

  • The suspendCoroutine function, used to suspend a coroutine execution and schedule its future continuation.
  • The startCoroutine extension function, used to start a coroutine by allowing a suspending function to be called from a regular function.

When using coroutines for asynchronous programming in the JVM we also need to take into account two additional facts:

  • There already exists a rich ecosystem of asynchronous functionalities in the JVM ecosystem, ranging from NIO2 asynchronous channels to reactive streams, which makes sense to use with coroutines. As an example, we may want to use a client library such as AsyncHttpClient, that returns a custom ListenableFuture or a circuit-breaker library such as Hystrix, that exposes its functionality via Observables.

  • Suspending functions can only be called directly from other suspending functions, however we may need to use a coroutine inside a regular function, such as a Spring MVC controller method.

The low-level suspendCoroutine and starCoroutine functions provide the means to implement the bridges between the coroutine world and the JVM asynchronous world, however some non-trivial code is still required. Fortunately, the Kotlin Library support coroutines (kotlinx.coroutines) already provides a rather rich set of functions with this purpose, divided into two sets:

  • Suspending functions that convert from asynchronous objects (e.g. CompletableFuture<String> instances), to plain objects (e.g. String instances).
  • Functions that expose coroutines to regular methods, using asynchronous objects.

Using asynchronous objects in suspending functions


Converting suspending functions into asynchronous objects