우찬쓰 개발블로그

코틀린 코루틴의 정석 본문

개발서 정복

코틀린 코루틴의 정석

이우찬 2024. 3. 31. 11:45
반응형

저자 조세영

 

코루틴 관련 문서나 책은 많이 읽었지만, 이렇게 깔끔하게 정리된 책은 처음보는것 같다.

 

덕분에 머리에서 정리가 잘 안되어 있거나 헷갈리던 부분을 다시 되짚어 볼 수 있었다.

 

아래는 자주 잊어버리는 부분만 정리.

 


코루틴은 스레드 블로킹을 해결하기 위해 등장했다. 스레드를 양보할 수 있다.

<CoroutineDispatcher>
- 코루틴을 쓰레드로 보내기 위한 역할

 

Dispatchers.IO
- 쓰레드 수 = JVM 프로세서수 or 64 중 큰 수
Dispatchers.Default
- 쓰레드 수 = CPU 코어수

- CPU연산(CPU 바운드 작업)에 주로 사용. 

<Coroutine Context 요소>
- CoroutineName
- CoroutineDispatcher
- Job
- CoroutineExceptionHandler

코틀린 취소는 자식으로 전파됨

예외 throw는 해당 코루틴에서 이미 처리된 것으로 보므로 그 부모이상에 exception handler를 넣어야함


예외를 더 위로(부모로) 전파하지 않기 위해

SupervisorJob
SubervisorScope

fun main() = runBlocking {
    val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
        println("[예외 발생] ${throwable}")
    }
    val supervisedScope = CoroutineScope(SupervisorJob() + exceptionHandler)
    supervisedScope.apply { 
        launch(CoroutineName("test1")) { 
            throw Exception("exception")
        }
        launch(CoroutineName("test2")) {
            delay(100)
            println("${Thread.currentThread().name}}")
        }
    }
    delay(1000L)
}



<코루틴 실행 순서>

fun main() = runBlocking { 
    launch { 
        println("task1")
    }
    println("task2")
}

// task2
// task1
// runBlocking 코루틴에서 양보하는 부분이 있어야 그 다음에 task1이 실행

fun main() = runBlocking {
    launch(start = CoroutineStart.UNDISPATCHED) {
        println("task1")
    }
    println("task2")
}

// task1
// task2
// Dispatcher 객체의 작업 대기열을 거치지 않고 곧바로 호출자의 스레드에 할당돼 실행



withContext
- 새로 코루틴 생성하는것 아님
- Coroutine Context를 변경 가능

mutex를 통해 다중 스레드 동시 접근을 막을 수 있음

var count = 0
val mutex = Mutex()
fun main() = runBlocking {
    withContext(Dispatchers.Default) {
        repeat(10000) {
            launch { 
                mutex.withLock { 
                    count += 1
                    mutex.unlock()
                }
            }
        }
    }
    println("count = $count")
}

 

advanceTimeBy 와 advanceUntilIdle
- advanceTimeBy는 특정 시간만큼 가상 시간이 흐르도록 하는 것
- advanceUntilIdle 는 TestCoroutineScheduler 에 연결된 모든 디스페처와 연결된 작업이 모두 완료될 때까지 가상 시간을 흐르게 만듦

반응형

'개발서 정복' 카테고리의 다른 글

불안한 완벽주의자를 위한 책  (0) 2024.01.22
리팩터링 2판  (0) 2023.11.14
Jetpack Compose Internals  (0) 2023.07.23
이펙티브 코틀린  (0) 2023.03.16
클린코더  (0) 2023.01.26
Comments