코틀린의 코루틴은 비동기 작업을 효율적이고 간결하게 처리할 수 있는 강력한 도구입니다. 이 글에서는 코루틴 스코프와 suspend 함수에 대해 간단히 설명하고, 왜 이를 사용하는 것이 좋은지 알아보겠습니다.
코루틴 스코프는 코루틴이 실행되는 공간을 의미합니다. 코루틴을 실행하고 관리하며, 모든 작업이 완료되면 스코프는 자동으로 정리(clean-up)됩니다.
여러 비동기 작업을 안전하게 실행하고, 필요할 경우 취소하거나 관리할 수 있습니다.
코루틴 스코프의 주요 역할:
작업 관리: 여러 코루틴을 하나의 스코프 안에서 실행.
자동 정리: 스코프 내 모든 작업이 끝나면 자원을 정리.
구조적 동시성: 비동기 작업을 구조적으로 관리해 코드 복잡도를 줄임.
코루틴 스코프 예시:
fun main() {
runBlocking { // 코루틴 스코프
launch { // 코루틴 실행
val result = fetchData()
println(result)
}
println("다른 작업을 실행 중입니다!")
}
}
runBlocking: 코루틴 스코프를 생성하고 블록 내의 작업이 모두 끝날 때까지 실행을 유지합니다.
launch: 코루틴을 실행합니다. 코루틴은 비동기로 작동하므로 다른 작업과 동시에 실행됩니다.
주방에서는 여러 요리사가 동시에 요리를 준비할 수 있어요.
각각의 요리사는 자기 요리를 하다가, 재료가 준비될 때까지 기다리거나 다른 요리를 도와줄 수 있어요.
suspend 함수는 요리사가 잠깐 멈추고 기다리는 것과 같아요.
요리사가 물을 끓이는 동안 물이 끓을 때까지 기다리면서 다른 요리를 준비하거나 쉬어요.
하지만 기다린다고 해서 주방이 멈추는 건 아니에요. 다른 요리사들은 계속해서 요리를 준비하니까요.
프로그래밍에서도 "기다려야 하는 일"이 자주 생겨요. 예를 들어:
인터넷에서 책 정보를 가져오는 일.
파일을 다운로드하는 일.
게임에서 상대방의 행동을 기다리는 일.
기다리는 동안 프로그램이 멈추면 사용자가 불편하겠죠? 코루틴은 프로그램이 멈추지 않고 다른 일을 계속할 수 있도록 도와줘요.
효율적인 작업 처리:
시간이 오래 걸리는 작업(예: 네트워크 요청, 파일 읽기 등)을 기다리는 동안 다른 작업을 처리할 수 있습니다.
코드 가독성:
콜백(callback) 중첩 없이 비동기 코드를 동기식 코드처럼 작성할 수 있습니다.
사용자 경험 개선:
메인 스레드를 블로킹하지 않기 때문에 앱이 더 부드럽게 작동합니다.
suspend 함수는 코루틴에서 특별히 멈추고 기다릴 수 있는 함수예요.
예를 들어, 인터넷에서 데이터를 가져오는 함수는 시간이 걸려요. 이런 함수는 suspend로 만들어져야 코루틴에서 사용자가 기다리는 동안 다른 일을 할 수 있어요.
kotlin
suspend fun boilWater(): String {
// 물을 끓이는 데 시간이 걸린다고 상상해봐요
delay(3000) // 3초 기다리기 (코루틴에서만 사용 가능)
return "물이 끓었어요!"
}
delay(3000)은 3초 동안 기다리라는 의미인데, 이 3초 동안 다른 작업이 멈추지 않도록 코루틴이 알아서 처리해줘요.
코루틴 스코프는 코루틴을 실행하는 공간이에요. 요리사의 주방처럼요.
예를 들어, 레스토랑에 요리사가 여러 명 있고, 각각의 요리사가 코루틴이라고 생각해요. 주방(코루틴 스코프)은 요리사들이 일을 하다가 끝나면 깨끗이 치워주는 역할을 해요.
코루틴 스코프 만들기
kotlin
fun main() {
runBlocking { // 코루틴 스코프
launch {
val result = boilWater()
println(result)
}
println("다른 작업을 하고 있어요!")
}
}
runBlocking: 주방을 열고 코루틴을 실행해요.
launch: 요리사 한 명이 일을 시작해요.
프로그램은 물이 끓을 동안(3초) 다른 작업(println)도 처리해요.
효율적이에요!: 오래 걸리는 작업(인터넷 요청, 파일 다운로드 등)을 기다리는 동안 다른 작업을 할 수 있어요.
간단해요!: 복잡한 코드를 깔끔하고 읽기 쉽게 만들 수 있어요.
다른 프로그램을 멈추지 않아요!: 사용자는 앱이 끊기지 않고 부드럽게 작동하는 걸 느낄 수 있어요.
코루틴 스코프는 여러 일을 동시에 할 수 있게 도와주는 작업 공간이에요.
suspend 함수는 잠깐 멈춰야 하는 함수인데, 멈춰도 프로그램 전체가 멈추지 않게 해줘요.
코루틴 덕분에 복잡한 비동기 작업을 더 쉽고 깔끔하게 처리할 수 있어요.
예를 들어, 사용자가 버튼을 눌러 데이터를 가져오는 동안, 메인 스레드는 UI를 업데이트하거나 애니메이션을 실행할 수 있습니다.
코드 예제
kotlin
import kotlinx.coroutines.*
fun main() {
runBlocking { // 메인 스레드를 차단하지 않는 코루틴 스코프
launch {
// 2초 동안 데이터를 가져오는 작업
println("데이터 가져오기 시작")
val data = fetchData()
println("가져온 데이터: $data")
}
// 동시에 다른 작업도 실행 가능
launch {
repeat(5) { i ->
println("UI 작업 중... $i")
delay(500) // 0.5초 대기
}
}
}
}
suspend fun fetchData(): String {
delay(2000) // 데이터를 가져오는 데 2초 소요
return "데이터 가져오기 성공"
}
실행 결과
위 코드를 실행하면 다음과 같은 결과를 볼 수 있습니다:
데이터 가져오기 시작
UI 작업 중... 0
UI 작업 중... 1
UI 작업 중... 2
UI 작업 중... 3
UI 작업 중... 4
가져온 데이터: 데이터 가져오기 성공
첫 번째 코루틴: 데이터를 가져오는 데 2초 걸립니다.
두 번째 코루틴: 0.5초마다 "UI 작업 중..."이라는 메시지를 출력합니다.
이 두 작업이 동시에 실행되며, 2초가 지나기 전에 UI 작업이 5번 출력됩니다.
메인 스레드의 역할
위에서 UI 작업 중... 메시지는 메인 스레드가 처리할 수 있는 작업을 예로 든 것입니다.
실제 앱에서는:
화면을 렌더링 (예: 리스트를 스크롤하거나 애니메이션 실행).
사용자 입력 처리 (예: 버튼 클릭, 스와이프 동작 등).
네트워크 요청 대기 중에도 앱이 부드럽게 작동.
코루틴의 suspend 함수는 작업을 잠깐 멈출 수 있지만, 메인 스레드는 멈추지 않고 계속 실행됩니다.
이로 인해 UI 작업과 비동기 작업을 동시에 처리할 수 있어, 사용자 경험이 크게 향상됩니다.