본문 바로가기
프로그래밍 놀이터/Kotlin, Coroutine

[Kotlin] Coroutine 에 대한 이해 : 기본 용어 및 사용

by 돼지왕 왕돼지 2020. 8. 7.
반응형


kotlin coroutine


https://android.jlelse.eu/coroutines-basic-terminologies-and-usage-b4242bd1b2a4


Coroutine 이 뭐냐?


-

Coroutine 은 suspendable computaion instance 이다.

코드 블럭이 life-cycle 을 가지고 생성되고 수행된다는 것이 개념상 thread 와 비슷하지만, 특정 thread 에 bound 되어 있지 않다.

한 thread 에서 실행되고, 다른 thread 에서 resume 될 수도 있다.

future 와 같이 result 나 exception 으로 종료될 수 있다.



-

Coroutine 은 lightweight thread 라고 볼 수 있다.

여러개의 function 을 async 로 호출할 수 있고, 더 짧은 시간 안에 효율적으로 결과를 얻을 수도 있다.



-

Coroutine 은 kotlin 의 language feature 이다.




Suspending Function


-

suspend 로 마킹된 suspending function 은 현재 thread 를 blocking 하지 않고, 코드 실행을 suspend 시킬 수 있다.

suspend function 은 result return 대신 context 를 return 한다.

다시 말해 code 의 일부분을 수행하고, context 와 남아있는 code 의 참조만을 유지한채 suspend 한다.

suspending function 은 coroutine 안에서 혹은 다른 suspend function 에서만 호출할 수 있다.




CoroutineBuilder


-

suspending lambda ( argument 에 suspend modifier 마킹 ) 를 argument 로 받을 수 있다.


launch { } : Job 을 return 하는 coroutine

async { } : Deffered 를 이용하여 single value 를 return 하는 coroutine. Deferred value 에 .await() 를 호출하여 최종 결과를 얻을 수 있다. Deferred 는 Job 이라, cancel 할 수도 있다.

runBlocking { } : current thread 를 block 시키는 coroutine



-

delay 는 thread 를 block 시키지 않고 코드 수행을 멈추는 특별한 suspending function 이다.




CoroutineScope


-

각각의 Coroutine 은 우리가 정의한 scope 안에서 수행된다.

그래서 우리는 Activity, Fragment 등의 life-cycle 을 생각하며 잘 짜야 한다.

모든 coroutine builder 는 CoroutineScope 의 extension 이다.



-

CoroutineScope 는 coroutineContext 와 같은 property 를 제공하며, coroutineContext 는 dispatcher, Job 등과 같은 여러 가지 element 의 set 이다.

Coroutine 이 active 인지는 Job 의 isActive property 를 체크할 수 있다.

GlobalScope 는 전체 app 전체 lifecycle 에서 수행될 수 있는 scope 이다.




CoroutineDispatcher


-

CoroutineDispatcher 는 coroutine 의 실행을 특정 thread 로 종속시킬 수 있다.

이 말은 CoroutineDispatcher 가 어떤 thread 에서 coroutine 이 실행되어야 하는지 결정한다는 것이다.



-

다음과 같은 dispatcher 들이 있다.


Dispatcher.Default : 모든 standard builder 들에 의해 사용되며, dispatcher 가 명시되지 않은 경우이다. bg thread 를 가진 shared common pool 에서 수행한다. 일반적인 bg job 을 수행할 때 적합하다.

Dispatcher.IO : 상황에 따라 thread 를 만드는 shared pool 을 사용하며, blocking 되는 IO 작업에 적합하다.

Dispatcher.Unconfined : 아무 thread 혹은 pool 에서 수행하는데, 일반적으로 code 에서 사용되지 않아야 좋다.

newSingleThreadContext : private single thread

newFixedThreadPoolContext : fixed size 로 private thread pool 을 만들어 수행한다.

asCoroutineDispatcher : Executor 를 dispatcher 로 변환하는 특별한 extension function 이다.



-

launch, async 와 같은 coroutine builder 들은 CoroutineContext param 을 받아 dispatcher 를 지정할 수 있다.

launch(Dispatchers.Default){ } 는 GlobalScope.launch{ } 와 같은 dispatcher 를 사용한다.




Job


-

개념적으로 job 은 life cycle 을 가진 cancel 가능한 녀석이며, 코드 수행을 마치면 destroy 된다.

이것은 parent-child hierarchy 를 가지며 parent 의 cancel 은 모든 children 의 cancel 을 야기한다.



-

child 의 CancellationException 을 제외한 exception 은  parent 를 즉각 cancel 시킨다.

이 방법으로 parent 는 자기 자신의 cancel 호출이 아닌 것으로도 모든 children 을 cancel 시킬 수 있다.



-

NonCancellable 을 이용해서 cancel 할 수 없는 job 을 만들 수도 있다.

withTimeout 을 통해서 cancel 도 시킬 수 있다.




Actor


-

actor 는 coroutine state, behavior, 다른 coroutine 과의 comm channel 의 조합이다.

actor 는 message stream 을 처리한다.

concurrent 하게 작동하면 안 되는 task 들을 관리하는 데도 사용된다.



-

Actor 는 여러번의 click 시 최초 혹은 최후의 click 에만 반응하게 하는 데 좋다.




Channels


-

Channel 은 sender 와 receiver 의 non-blocking comm channel 이다.

blocking 대신 suspend 를 사용한다.

이 녀석은 coroutine 간의 value stream 전송을 담당한다.




Structured Concurrency


-

thread 는 기본적으로 global 이다.

그러나 coroutine 은 항상 UI element 등 local scope 와 관련되어 있다.

그래서 우리는 coroutine 을 수행할 때 특정한 scope 를 지정해줘야 한다.




Android


-

안드로이드에서 우리는 coroutine dispacher context 를 main UI thread 로 한정하고 싶을 때가 많다.

이는 kotlinx-coroutines-android lib 을 dependency 로 걸어서 수행할 수 있다.

여기서는 Dispatchers.Main context 를 제공한다.



-

끝!!!





반응형

댓글