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

Kotlin의 코루틴은 어떻게 동작하는가

Kotlin의 코루틴은 어떻게 동작하는가

* DroidKnights 2018
* Kotlin coroutine에 대한 101 세션 자료

Avatar for Chang W. Doh

Chang W. Doh

April 23, 2018
Tweet

More Decks by Chang W. Doh

Other Decks in Programming

Transcript

  1. fun fetchUserDetail(id: String) { val token = auth() val user

    = getUser(token, id) updateUserData(user) } BVUI Waaaaa~~it HFU6TFS VQEBUF6TFS%BUB 8BBBBB__JU
  2. fun fetchUserDetail(id: String) { auth { token -> getUser(token) {

    updateUserData(it) } } } BVUI HFU6TFS VQEBUF6TFS%BUB
  3. suspend fun fetchUserDetail(id: String) { val token = auth() val

    user = getUser(token, id) updateUserData(user) } suspend BVUI *%-& /POCMPDLJOH HFU6TFS VQEBUF6TFS%BUB *%-& /POCMPDLJOH
  4. fun plusOne(initial: Int) : Int { val ONE = 1

    var result = initial result += ONE return result }
  5. public interface Continuation<in T> { } public val context: CoroutineContext

    public fun resume(value: T) public fun resumeWithException(exception: Throwable)
  6. suspend fun fetchUserDetail(id: String) { val token = auth() val

    user = getUser(token, id) updateUserData(user) } }
  7. suspend fun fetchUserDetail(id: String) { // ... switch (label) {

    case 0: val token = auth() case 1: val user = getUser(token, id) case 2: updateUserData(user) } }
  8. fun fetchUserDetail(id: String) { // ... switch (label) { case

    0: val token = auth() case 1: val user = getUser(token, id) case 2: updateUserData(user) } } -BCFMJOH
  9. fun fetchUserDetail(id: String, cont: Continuation) { switch ( label) {

    case 0: auth( ) case 1: getUser(token, id ) case 2: … } } val sm = object : CoroutineImpl { ... } sm. sm , sm 4UBUF.BDIJOF
  10. fun fetchUserDetail(id: String, cont: Contiunation) { val sm = object

    : CoroutineImpl { ... } switch (sm.label) { case 0: auth(sm) case 1: getUser(token, id, sm) case 2: … } } $POUJOVBUJPO
  11. fun fetchUserDetail(id: String, cont: Contiunation) { val sm = object

    : CoroutineImpl { ... } switch (sm.label) { case 0: sm.id = id sm.label = 1 auth(sm) … } } 4BWFTUBUFT
  12. fun fetchUserDetail(id: String, cont: Contiunation) { val sm = object

    : CoroutineImpl { ... } switch (sm.label) { … case 1: val id = sm.id val token = sm.result as String sm.label = 2 getUser(token, id, sm) … } 3FTUPSFTUBUF
  13. fun fetchUserDetail(id: String, cont: Contiunation) { val sm = object

    : CoroutineImpl { fun resume(...) { fetchUserDetail(null, this) } } switch (sm.label) { case 0: … } } 3FTVNF DBMMCBDL
  14. fun fetchUserDetail(id: String, cont: Contiunation) { val sm = cont

    as? ThisSM ?: object : CoroutineImpl { fun resume(...) { fetchUserDetail(null, this) } } switch (sm.label) { case 0: … } } $POUJOVBUJPO SFVTF
  15. public interface Continuation<in T> { } public val context: CoroutineContext

    public fun resume(value: T) public fun resumeWithException(exception: Throwable)
  16. fun updateUserDetail(id: String) = launch(UI) { val token = auth()

    val user = getUser(token, id) updateUserDataOntoUI(user) }
  17. class DispatchedContinuation<in T> ( val dispatcher: CoroutineDispatcher, val continuation: Continuation<T>

    ) : Continuation<T> by continuation { override fun resume(value: T) { dispatcher.dispatch(context, DispatchTask(...)) } ... }
  18. fun launchOnUiThread() { launch(UI) { delay(1000L) ... } } /**

    * Dispatches execution onto Android main UI thread * and provides native [delay][Delay.delay] support. */ val UI = HandlerContext(Handler(Looper.getMainLooper()), "UI")
  19. fun main(args: Array<String>) = runBlocking<Unit> { val jobs = arrayListOf<Job>()

    jobs += launch(Unconfined) { println("'Unconfined': I'm working in thread ${Thread.currentThread().name}") } jobs += launch(coroutineContext) { println("'coroutineContext': I'm working in thread ${Thread.currentThread().name}") } jobs += launch(CommonPool) { println("'CommonPool': I'm working in thread ${Thread.currentThread().name}") } jobs += launch(newSingleThreadContext("MyOwnThread")) { println("'newSTC': I'm working in thread ${Thread.currentThread().name}") } jobs.forEach { it.join() } } 6ODPOGJOFE*NXPSLJOHJOUISFBENBJO $PNNPO1PPM*NXPSLJOHJOUISFBE'PSL+PJO1PPMDPNNPO1PPM XPSLFS OFX45$*NXPSLJOHJOUISFBE.Z0XO5ISFBE DPSPVUJOF$POUFYU*NXPSLJOHJOUISFBENBJO
  20. fun main(args: Array<String>) = runBlocking<Unit> { launch { repeat(1000) {

    i -> println("I'm sleeping $i ...") delay(500L) } } delay(1300L) // just quit after delay } I'm sleeping 0 ... I'm sleeping 1 ... I'm sleeping 2 ...
  21. fun main(args: Array<String>) = runBlocking<Unit> { val job = launch

    { try { repeat(1000) { i -> println("I'm sleeping $i ...") delay(500L) } } finally { println("I'm running finally") } } delay(1300L) // delay a bit println("main: I'm tired of waiting!") job.cancelAndJoin() // cancels the job and waits for its completion println("main: Now I can quit.") } I'm sleeping 0 ... I'm sleeping 1 ... I'm sleeping 2 ... main: I'm tired of waiting! I'm running finally main: Now I can quit.
  22. fun main(args: Array<String>) = runBlocking<Unit> { withTimeout(1300L) { repeat(1000) {

    i -> println("I'm sleeping $i ...") delay(500L) } } } I'm sleeping 0 ... I'm sleeping 1 ... I'm sleeping 2 ... Exception in thread "main" kotlinx.{…}.TimeoutCancellationException …