다시 돌아온 코루틴!
그럼 바로 문제부터 시작해볼까요?
문제1
다음 코드는 언제 끝날까요?
fun main() = runBlocking {
val job = launch {
while (true) {
println("While in ${Thread.currentThread().name}")
}
}
}
정답
이 코드는 안끝납니다!
launch 스코프로 실행하고 runBlocking 이 끝날 때 까지 기다리기 때문에 무한루프를 타게 됩니다.
문제 2
그럼 이 녀석은 언제 끝날까요?
fun main() = runBlocking {
val job = launch {
while (true) {
println("While in ${Thread.currentThread().name}")
}
}
println("종료")
job.cancel()
println("종료 끝")
}
정답
바로 끝납니다!
cancel() 로 job 을 끝내버리기 때문이죠
문제 3
그럼 코드는 끝나는데 몇 초 걸릴까요?
fun main() = runBlocking {
val job = launch {
while (true) {
println("While in ${Thread.currentThread().name}")
}
}
delay(1000L)
job.cancel()
}
정답
1초..일줄 알았지만 사실 끝나지 않습니다!
delay 를 만나는 순간 제어권을 launch 스코프에서 가져가고 무한루프가 실행되기 때문이죠.
delay 의 내부를 보면 좀 더 이해할 수 있습니다!
yield 도 마찬가지입니다ㅎㅎ
이렇게 재밌는 코루틴을 공부해봅시다!
Dispatcher
스레드 풀을 관리하고 코루틴을 실행 또는 재개할 스레드를 결정한다.
서버 통신과 같이 오래걸리고 가벼운 작업이 여러개의 스레드를 사용한다.
따라서 코루틴을 잘 사용하려면 언제 어떤 dispatcher 를 사용할 지 잘 알아야합니다.
여러 Dispatcher 가 존재합니다.
Default Dispatcher
JVM의 공유 스레드 풀을 사용하며 동시 작업의 최대 수는 CPU의 코어 수(엄밀히 말하면 물리적 스레드 수)와 같다.
IO Dispatcher
- IO Dispatcher는 Default Dispatcher와 스레드 풀을 공유한다.
- 최대 64개까지의 스레드를 생성
- withContext(Dispatchers.IO)로 감싸서 일시 중단 함수로 만들면 가장 좋다.
Main Dispatcher
- 안드로이드에서만 존재하는 Dispatcher
- 메인 스레드가 UI와 상호작용하는 데 사용
- Main 스레드가 차단되면 전체 애플리케이션이 중지
CoroutineScope vs WithContext
CoroutineScope
코루틴의 수명 주기를 관리하기 위한 스코프를 제공한다.
해당 Dispatcher 에 새로운 스코프를 연다.
CoroutineScope(Dispatchers.IO).launch { }
WithContext
withContext(Dispatchers.IO) { launch { } }
컨텍스트를 일시적으로 변경한다.
with context 는 async await 이 합쳐진 형태다.
실행 블록이 완료되면 코루틴이 일시 중단되고 원래 컨텍스트(withContext가 호출된 곳)가 복원된다.
즉, 비동기 코드 안에서 사용하면 동기적으로 작동하게 할 수 있다.
GlobalContext
전체 애플리케이션 수명 주기 동안 존재한다. 앱이 죽을 때 까지 존재하고 계속 실행된다.
coroutineScope(소문자)
현재 스코프의 컨텍스트를 상속받는 새 코루틴 스코프를 연다.
ViewModelScope
아마 현재 안드로이드에서 가장 많이 사용하는 스코프가 아닐까
이 범위에서 시작된 모든 코루틴 스코프는 뷰모델이 삭제되면 자동으로 취소된다.
ViewModel이 활성 상태인 경우에만 실행해야 할 작업이 있으면 유용하다.
class SomeViewModel(
private val someDefaultRepository: SomeRepository
): ViewModel() {
fun setSomething(something: String) {
viewModelScope.launch(Dispatchers.IO) {
someDefaultRepository.postSomething(something)
}
}
}
'우아한테크코스' 카테고리의 다른 글
자동 DI 라이브러리 만들기 : [우아한테크코스 5기 AN_베르] (0) | 2023.10.02 |
---|---|
[안드로이드] App 로깅 전략 with Firebase Analytics [우아한테크코스 5기 AN_베르] (0) | 2023.08.06 |
Kotlin coroutine 강의로 이해하기 - 1 : [우아한테크코스 5기 AN_베르] (0) | 2023.07.16 |
[안드로이드] MVP 패턴을 MVVM 패턴으로 리팩터링하기 (0) | 2023.07.09 |
Presenter 테스트 작성하기 (안드로이드 MVP) : [우아한테크코스 5기 AN_베르] (0) | 2023.06.23 |