코루틴 동시성

    Coroutine 공유 상태와 동시성 2편 - Thread-safe한 데이터 구조, 세밀하게 Thread 제한하기, 굵게 Thread 제어하기

    Thread-safe한 데이터 구조 Threads과 Coroutines에 모두 작동하는 일반적인 해결 방법은 공유 상태에 수행되어야하는 모든 동작에 대한 필수적인 동기화를 제공하는 스레드 안전한(동기화된, 선형성, 원자성 이라고도 부름) 데이터 구조를 사용하는 것이다. 간단한 카운터에 대해서는 incrementAndGet 이라 불리는 원자적인 동작을 제공하는 AtomicInteger 클래스를 사용할 수 있다. val counter = AtomicInteger() fun main() = runBlocking { withContext(Dispatchers.Default) { massiveRun { counter.incrementAndGet() } } println("Counter = $counter") } ..

    Coroutine 공유 상태와 동시성 1편 - Coroutine을 여러개 실행했을 때의 문제점, Volatile은 동시성 문제를 해결하지 못한다.

    Coroutine은 Dispatchers.Default와 같이 멀티 스레드를 관리하는 Dispatcher에 의해 병렬적으로 실행될 수 있다. 이는 병렬 실행 시 일어날 수 있는 일반적인 문제들을 모두 만들어낸다. 가장 주요한 문제는 변경 가능한 공유 상태의 동기화이다. Coroutine에서 이 문제에 대한 일부 해결 방식은 멀티 스레드 세계에서의 해결방식과 유사하지만, 다른 해결 방식들은 Coroutine에만 있다. Coroutine을 여러개 실행했을 때의 문제점 같은 동작을 수천번 하는 수백개의 Coroutine을 실행한다고 하자. 이후의 추가 비교를 위해 완료 시간을 측정한다 : suspend fun massiveRun(action: suspend () -> Unit) { val n = 100 // ..

    Coroutines 일시중단 함수 구성하기 2편 - 비동기 스타일 함수, 구조화된 동시성과 async

    비동기 스타일 함수 구조적인 동시성에서 벗어나기 위해 GlobalScope를 참조하는 async Coroutine Builder을 사용하여 doSomethingUsefulOne 및 doSomethingUsefulTwo을 실행하는 비동기 스타일의 함수를 정의할 수 있다. 이러한 함수들의 이름은 "...Async"를 접미사를 가지도록 하여, 함수들이 비동기 계산을 시작하기만 하고 결괏값을 얻기 위해 Deffered 값을 사용해야 한다는 것을 강조한다. 📖 GlobalScope는 사소하지 않은 역효과를 일으킬 수 있는 섬세하게 다뤄야 하는 API이다. 그 중 하나는 아래에서 설명될 것이며, 명시적으로 GlobalScope를 @OptIn(DelicateCoroutinesApi::class)과 함께 사용되도록 해..