분류 전체보기
Coroutines와 Channels 튜토리얼 - 1. 시작하기 전 준비하기
이 튜토리얼에서는 IntelliJ IDEA를 사용해, 실행중인 Thread나 Callback을 블록하지 않고 코루틴을 사용하여 네트워크 요청을 수행하는 방법을 살펴볼 것이다. 📖 당신은 Kotlin 기초 구문에 익숙해야 하지만, Coroutines에 대한 사전 지식은 필요하지 않습니다. 당신은 다음의 사항들에 대해 배울 것입니다. 네트워크 요청을 하기 위해 일시 중단 함수를 왜 그리고 어떻게 사용해야 하는지 Coroutines을 사용하여 요청을 동시에 보낼 수 있는 방법 서로 다른 Coroutines 간에 Channels를 이용하여 정보를 공유하는 방법 네트워크 요청들을 위해서 Retrofit 라이브러리를 필요로 하지만, 이 튜토리얼에서 보여지는 접근 방식은 보편적이고 Coroutines를 지원하는 다른..
IntelliJ IDEA 사용해 Kotlin Flow 디버깅 하기
이 튜토리얼은 IntelliJ IDEA를 사용해 Kotlin Flow를 생성하고 디버깅 하는 방법에 대해 설명한다. 이 튜토리얼에서는 독자들이 Coroutine 개념에 대한 사전 지식이 있다고 가정한다. Kotlin Flow 생성하기 느린 방출기와 느린 수집기를 가진 Kotlin flow를 생성한다: 1. Intellij IDEA에서 Kotlin 프로젝트를 연다. 만약 프로젝트가 없다면 하나를 새로 만든다. 2. kotlinx.coroutines 라이브러리를 Gradle 프로젝트에서 사용하기 위해서 다음 종속성을 build.gradle(.kts)에 추가한다. Kotlin Gradle dependencies { implementation("org.jetbrains.kotlinx:kotlinx-corouti..
IntelliJ IDEA 사용해서 Coroutine 디버깅 하기
이 튜토리얼은 IntelliJ IDEA를 사용해 Kotlin Coroutine을 만들고 디버깅하는 방법을 설명한다. 이 튜토리얼에서는 독자들이 Coroutine 개념에 대한 사전 지식이 있다고 가정한다. Coroutine 생성하기 1. Intellij IDEA에서 Kotlin 프로젝트를 연다. 만약 프로젝트가 없다면 하나를 새로 만든다. 2. kotlinx.coroutines 라이브러리를 Gradle 프로젝트에서 사용하기 위해서 다음 종속성을 build.gradle(.kts)에 추가한다. Kotlin Gradle dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") } Groovy Gradle depende..
Coroutine 공유 상태와 동시성 3편 - Mutex 사용하기, Actors 사용하기
Mutex 사용하기 문제에 대한 상호 배제 솔루션은 모든 모든 공유 상태에 대한 변경을 절대로 동시에 실행되지 않는 critical section*1으로 만들어 보호하는 것이다. 블로킹을 수행하기 위해서는 일반적으로 synchronized나 ReentrantLock을 사용한다. Coroutine의 대체제는 Mutex*2라 불린다. 이는 critical section을 구분하기 위한 lock과 unlock 함수를 가진다. 중요한 차이점은 Mutext.lock()이 일시중단 함수라는 것이다. 이는 Thread를 블록하지 않는다. mutex.lock(); try { ... } finally { mutex.unlock() } 패턴을 나타내는 withLock 확장함수 또한 있다. val mutex = Mutex(..
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") } ..