디버깅을 하기 위한 준비
Kotlin Coroutines는 일시 중단 후에는 다른 스레드에서 실행될 수 있기 때문에 디버깅을 하기가 매우 어렵다. 이 글에서는 디버깅을 하기 어려운 예 중에 가장 간단한 예시를 제시할 것이다.
다음의 코드를 보자.
import kotlinx.coroutines.*
fun main() = runBlocking<Unit> {
launch(Dispatchers.Unconfined) {
println("launch1 Working Thread : ${Thread.currentThread().name}")
delay(100)
println("launch1 Working Thread : ${Thread.currentThread().name}")
}
launch {
println("launch2 Working Thread : ${Thread.currentThread().name}")
delay(100)
println("launch2 Working Thread : ${Thread.currentThread().name}")
}
}
위 코드를 출력하면 어떻게 될까? 이 질문에 정확히 대답할 수 있는 개발자는 많지 않을 것이다.
이 코드의 출력은 다음과 같다.
launch1 Working Thread : main @coroutine#2
launch2 Working Thread : main @coroutine#3
launch1 Working Thread : kotlinx.coroutines.DefaultExecutor @coroutine#2
launch2 Working Thread : main @coroutine#3
출력이 위와 같이 나오는 이유는 launch1의 Dispatcher가 Dispatchers.Unconfined로 지정되어 있기 때문에 delay(100) 이후에 delay가 실행되는 Thread인 Default Executor Thread로 바뀌기 때문이다.
위와 같이 실행 Thread를 예측하기 어려운 상황에서 IntelliJ IDEA를 사용해 디버깅을 해보도록 하자.
IntelliJ IDEA 사용한 디버깅 방법
1. 브레이크 포인트 걸기
위 코드를 IntelliJ IDEA를 사용해 디버깅 하기 위해서는 아래 [그림1]과 같이 브레이크 포인트를 걸어주어야 한다.
2. 디버깅 실행하기
1번이 완료되었으면 fun main() 왼쪽의 재생 버튼을 눌러 나오는 옵션 중 [Debug '파일명'] 을 누른다.
3. 디버깅 창의 Coroutines 탭 확인하기
디버깅 창의 Coroutines 탭을 확인하면 현재 실행중인 Coroutine 과 일시 중단 중인 Coroutine을 모두 확인할 수 있다.
디버깅에서는 Coroutine 현재 상태(RUNNING, SUSPENDED)는 물론 생성 스택, 로컬 변수와 캡처된 변수들까지 확인이 가능하다. 예를 들어 위의 coroutine:3을 펼쳐보면 다음과 같은 정보가 나온다.
4. 디버깅 정보 분석하기
위 코드에서 Dispatcher.Unconfined로 설정하면 마지막 실행 스레드로 실행 스레드가 바뀌는 것을 이야기 했다. 실제로 어떤 스레드에서 실행되는지 디버그 창에서 확인해보자.
아래 정보를 보면 Dispatchers.Unconfined에서 coroutine:2가 실행중이며, coroutine:2 는 DefaultExecutor 에서 실행 되는 것을 확인할 수 있다.
Kotlin Coroutines 공식 기술 문서 번역이 GitHub 오픈소스로 배포되었습니다. Starganizer가 되어 오픈소스를 지지해주세요.