동기화 블로킹멀티 스레딩, 멀티 프로세싱에서 중요한 것은 공유 상태 및 경쟁 상태이다. 다른 스레드에서 하나의 값을 수정, 조회할 때 서로 다른 값이 출력된다. 그래서 다음과 같은 코드에서는 예상하는 값이 나오지 않는다.suspend fun main(): Unit { var i = 0 coroutineScope { repeat(1_000_000) { launch { i++ } } } println(i) // ~998242} 자바에서 사용되는 `synchronized` 블록이나 동기화된 컬렉션을 사용해 해결할 수 있다. var i = 0fun main() = runBlocking { val lock = Any() re..
Kotlin Coroutines
안드로이드에서 스코프 만들기대부분의 안드로이드 애플리케이션에는 MVC 모델을 기반으로 한 MVVM이나 MVP 아키텍처가 사용되고 있다. 이러한 아키텍처에서는 사용자에게 보여 주는 부분을 `ViewModels` 나 `Presenters`와 같은 객체로 추출한다. (일반적으로 코루틴이 가장 먼저 시작되는 객체)`UseCase` 나 `Repository`와 같은 다른 계층에서는 보통 중단 함수를 사용한다. 다음 코드는 `BaseViewModel`을 아래의 조건을 만족하여 만든 것이다.- 모든 뷰모델에서 쓰일 스코프를 단 한 번으로 정의- 메인 디스패처로 컨텍스트 정의- 스코프를 취소 가능하게 만들되, 스코프가 가지고 있는 자식 코루틴만 취소- 스코프에서 시작된 각각의 코루틴이 독립적으로 작동- 잡히지 않는 예..
기본 디스패처디스패처를 설정하지 않으면 기본적으로 설정되는 디스패처는 CPU 집약적인 연산을 수행하도록 설계된 `Dispatchers.Default`이다.이 디스패처는 코드가 실행되는 컴퓨터의 CPU 개수와 동일한 수(최소 두 개 이상)의 스레드 풀을 가지고 있다. CPU 집약적인 연산을 수행하며 블로킹이 일어나지 않는 환경 같이 스레드를 효율적으로 사용하고 있다고 가정하면 이론적으로는 최적의 스레드 수라고 할 수 있다.다음 코드를 통해 디스패처를 확인할 수 있다.suspend fun main(): Unit = coroutineScope { repeat(1_000) { launch(Dispatchers.Default) { List(1000) { Random...
생각의 흐름데이터를 동시에 가져와야 할 상황에서 `getUserPorfile` 함수가 있다고 생각해 보자.다음 예제에서 중단 함수에서 중단 함수를 호출한다. 데이터를 동시에 가져와야 할 상황에서는 적합하지 않다. (2초가 걸리기 때문에)suspend fun getUserProfile(): UserProfileData { val user = getUserData() // 1초 후 val notifications = getNotifications() // 1초 후 return UserProfileData( user, notifications )} ?? : 아니 그럼 `GlobalScope` 사용해서 `async` 사용하면 되는 거 아님? ㅋㅋsuspend fun getUserProfi..