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

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

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

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

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 …