Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Kotlin Coroutine

Introduction to Kotlin Coroutine

This talk introduces Kotlin Coroutine, which was a big feature of Kotlin 1.1.

Kotlin coroutine is a suspendable computation. It empowers programmers in some use cases such as async/await, generator.

The talk describes what Kotlin coroutine is and explains suspendCoroutine method behind it.

Reference:
- https://kotlinlang.org/docs/reference/coroutines.html
- https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#use-cases
- https://github.com/Kotlin/kotlin-coroutines

- Introduction to Kotlin Coroutine
https://vimeo.com/222499934
slides: https://www.slideshare.net/elizarov/introduction-to-kotlin-coroutines
- Guide to kotlinx.coroutines by example

https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md

Hiroshi Kurokawa

October 27, 2017
Tweet

More Decks by Hiroshi Kurokawa

Other Decks in Technology

Transcript

  1. WHAT’S COROUTINE? A coroutine can be thought of as an

    instance of suspendable computation i.e. the one that can suspend at some points and later resume execution possibly on another thread. https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#use-cases
  2. THREAD-BLOCKING CODE SAMPLE val request = composeRequest() val post =

    makeRequest(request) parsePost(post) fun composeRequest(): Request = … fun makeRequest(request: Request): Result = … main composeRequest makeRequest If it takes a long time? If it takes a long time?
  3. THREAD-BLOCKING CODE SAMPLE val request = composeRequest() val post =

    makeRequest(request) parsePost(post) fun composeRequest(): Request = … fun makeRequest(request: Request): Result = … main composeRequest makeRequest If it takes a long time? If it takes a long time? The thread is blocked!
  4. SUSPEND TO THE RESCUE val request = composeRequest() val post

    = makeRequest(request) parsePost(post) suspend fun composeRequest(): Request = … suspend fun makeRequest(request: Request): Result = … 1 2 ‣ The code suspends at the suspension points ‣ The code resumes when the return value is ready
  5. SUSPEND TO THE RESCUE val request = composeRequest() val post

    = makeRequest(request) parsePost(post) suspend fun composeRequest(): Request = … suspend fun makeRequest(request: Request): Result = … 1 2 main composeRequest makeRequest main main 1 2
  6. SUSPEND TO THE RESCUE val request = composeRequest() val post

    = makeRequest(request) parsePost(post) suspend fun composeRequest(): Request = … suspend fun makeRequest(request: Request): Result = … 1 2 main composeRequest makeRequest main main 1 2 The thread is not blocked!
  7. CODE CAN BE WRITTEN IN A REGULAR STYLE try {

    for (req in list) makeRequest(req) } catch (e: Exception) { … } loop exception handling
  8. CAVEAT ‣ “Kotlin suspending functions are designed to imitate sequential

    behaviour by default”,
 Roman Elizarov (https://www.slideshare.net/elizarov/introduction-to-kotlin-coroutines) ‣ Concurrency has to be explicit
  9. val first = loadImageAsync("green") val second = loadImageAsync("red") overlay(first.await(), second.await())

    fun loadImageAsync(name: String) = async { … } ASYNC/AWAIT 1 2 main loadImageAsync main main 2 loadImageAsync 1
  10. SUSPEND COROUTINE suspend fun <T> suspendCoroutine( block: (Continuation<T>) -> Unit

    ): T ‣ When the method is called, it suspends the current coroutine ‣ The coroutine is resumed when resume() is called on the passed continuation Scheme call/cc style!
  11. SUSPEND COROUTINE suspendCoroutine { cont: Continuation<T> -> doLongTask { result,

    exception -> if (exception == null) cont.resume(result) else cont.resumeWithException(exception) } } fun <T> doLongTask(cb: (T, Throwable) -> Unit) { } suspend fun <T> suspendCoroutine( block: (Continuation<T>) -> Unit ): T
  12. SUSPEND COROUTINE suspend fun <T> doLongTaskSuspend() = suspendCoroutine { cont:

    Continuation<T> -> doLongTask { result, exception -> if (exception == null) cont.resume(result) else cont.resumeWithException(exception) 䠼} 䠼} result = doLongTaskSuspend() … // do something with the result
  13. val request = composeRequest() val post = makeRequest(request) parsePost(post) CONTINUATION

    1 2 Continuation
 passed to (2) No deep stacks and light-weight $ ‣ Kotlin builds a state machine for each coroutine ‣ A suspension point just adds a state to the state machine
  14. COROUTINE BUILDER ‣ Suspending function only can be called from

    a suspending function or a coroutine ‣ Use coroutine builders to call suspending functions from a regular function ‣ launch ‣ runBlocking ‣ async
  15. COROUTINE BUILDER fun postItem(item: Item) { launch(CommonPool) { val token

    = preparePost() val post = submitPost(token, item) processPost(post) } }
  16. WRAP UP ‣ Coroutine is like a light-weight thread ‣

    Can be suspended/resumed ‣ async/await, generator, channel is just library built on that