반응형

이 게시물은 다음 링크를 참조하여 학습했습니다

 

Coroutines guide | Kotlin

 

kotlinlang.org

 

Kotlin Coroutine Basic-1

Before start work on the coroutine, First, we have to know about the most common component using in a coroutine. Let’s start with some…

abhiappmobiledeveloper.medium.com

 

Concurrency vs Parallelism

This article will explain the difference between concurrency and parallelism. Concurrency vs parallelism has been a debated topic for a long time.

www.codeproject.com

 

[Kotlin] 코루틴 #4 - CoroutineBuilder와 ScopeBuilder

코루틴 #4 - CoroutineBuilder와 ScopeBuilder Coroutine Scope를 생성하는 Coroutine Builder에 대한 설명 (코루틴 빌더 = 스코프 빌더 같은 의미) launch / async / withContext / runBlocking / actor / produc..

jaejong.tistory.com

 

코루틴에 대해서는 이전에 정리한 글이 있긴한데, 그때는 당장 구현을 위해 핵심이 될 내용만 정리를 했다면 이번에는 개념위주로 확실하게 이해하고 정리하고자 한다.

코루틴 공식문서와 정리가 잘된 강의가 있어서 해당 내용을 정리해서 게시물을 작성했다.

 

1. Coroutines

Coroutines은 Cooperative + Routines의 합성어이다.

핵심은 kotlin의 ko가 아니라 co라는점....

코루틴은 다양한 기능을 제공하지만 대표적으로 비동기 프로그래밍을 구현할 때 사용하는 것으로 알고있다.

기존에 스레드로도 비동기를 구현할 수 있지만 이에비해 성능적, 문법적으로 장점을 갖고 있다.

 

코루틴은 다음과 같은 특징을 갖고 있다.

- 기본옵션으로 협력형이며 병행형으로 동작하지 않음(옵션은 조절 가능)
- 스케줄러가 실행시점을 결정하는 것이 아닌 프로그래머나 이벤트에 의해 실행 및 지연(suspend), 재개(resume)시점이 결정됨
- 비선점형 멀티태스크, 동시성(concurrency) 제공
- 독립적 스택을 가질 수도 있으나 일반적으로 스택을 다시 생성하지 않음

 

이와 비교해 스레드는 다음과 같은 특징을 갖는다.

- 개수에 따라 완전히 병행형으로 동작할 수 있음
- OS의 스케줄러가 실행시점을 결정함
- 선점형 멀티태스크, 멀티프로세싱, 병행성(parellelism) 제공
- 스레드별 독립적인 스택을 가지게 됨

 

1-1. 동시성 vs 병행성

동시성은 하나의 코어에서 여러 개의 task를 동시에 수행한다. 

반면에 병행성은 여러 개의 코어가 여러 개의 task를 각자 수행한다.

이번에 새로 알게된 점은 코루틴을 찍먹했을때는 병행성으로 동작하는줄 알았는데, 사실은 동시성이 default라는 점!

 

2. Coroutine components

코루틴은 기본적으로 다음 형태의 컴포넌트 구조를 갖는다.

 

2-1. CoroutineScope

(1) viewModelScope

viewModelScope는 viewModel이 사라질때 같이 사라진다.

viewModel 인스턴스에서 사용하기 적합하다.

 

(2) LifeCycleScope

LifeCycleScope는 Lifecycle object에 따라서 정의된다.

Android에서 LifecycleOwner는 Activity나 Fragment가 된다.

lifecycle.coroutineScope 또는 lifecycleOwner.lifecycleScope를 통해 Lifecycle의 CoroutineScope에 접근할 수 있다.

 

(3) GlobalScope

GlobalScope는 application과 생명주기를 함께한다.

때문에 GlobalScope를 과도하게 사용하면 어플리케이션 동작에 문제를 줄 수 있다.

 

2-2. CoroutineContext

코루틴 컨텍스트는 코루틴에 사용하는 스레드 또는 스레드를 결정하는 코루틴 디스패처를 포함한다.

코루틴 디스패처는 코루틴의 실행을 특정 스레드로 제한하거나, 스레드 풀에 보내거나, 제한 받지 않는 상태로 실행할 수 있다.

launch { // context of the parent, main runBlocking coroutine
    println("main runBlocking      : I'm working in thread ${Thread.currentThread().name}")
}
launch(Dispatchers.Unconfined) { // not confined -- will work with main thread
    println("Unconfined            : I'm working in thread ${Thread.currentThread().name}")
}
launch(Dispatchers.Default) { // will get dispatched to DefaultDispatcher 
    println("Default               : I'm working in thread ${Thread.currentThread().name}")
}
launch(newSingleThreadContext("MyOwnThread")) { // will get its own new thread
    println("newSingleThreadContext: I'm working in thread ${Thread.currentThread().name}")
}

 

 

2-3. CoroutineBuilder

코루틴 빌더는 코루틴 스코프의 확장함수로, 다양한 요구사항에 맞게 개별적인 코루틴을 만들 수 있다.

코루틴 빌더의 종류

- launch

결과값이 없는 코루틴을 생성하는 빌더, Job객체를 반환한다.

 

- async

결과값이 있는 코루틴을 생성하는 빌더, Deferred<T>를 반환한다.

결과값을 받는다는 의미인 await() 함수와 함께 사용한다.

 

- withContext

async처럼 결과값이 있는 코루틴을 생성하는 빌더, 결과값 T를 반환한다.

async가 await을 통해 결과값을 지연해서 받을 수 있다면, withContext는 그자리에서 반환한다.

 

- runBlocking

runBlocking은 Scope내의 코루틴들이 모두 완료할 때까지 스레드를 점유한다.

 

- actor

- produce

 

3. Structured concurrency

코루틴 공식문서에선 Structured concurrency를 강조한다.

한글로 번역하면 "구조적 동시성"인데, 쉽게 이야기하면

특별한 이유가 있지 않으면 코루틴 스코프를 무분별하게 생성하지 않고 부모 컨텍스트의 빌더를 사용하는 것이다.

실제 앱에선 많은 코루틴을 사용하게 되는데, 코루틴 스코프 내에서 코루틴 스코프를 중첩으로 사용하게 되면 상위 스코프에서의 Exception을 무시하고 하위 스코프의 내용을 실행할 수 있다.

 

반응형

+ Recent posts