728x90
반응형
이번 글에서는 코틀린에서 비동기 작업을 효율적으로 처리할 수 있는 코루틴(Coroutines)을 다루어 보겠습니다. 코루틴은 비동기 프로그래밍을 쉽고 읽기 좋게 만드는 코틀린만의 강력한 기능입니다.
1. 코루틴이란?
코루틴은 경량 스레드라고 생각할 수 있습니다. 스레드보다 훨씬 가볍고 효율적이며, 수천 개의 코루틴을 동시에 실행할 수도 있습니다.
(1) 주요 특징
- 비동기 코드를 동기 코드처럼 작성할 수 있습니다.
- 기본적으로 스레드 차단(blocking)이 없으므로 자원을 효율적으로 사용할 수 있습니다.
- suspend 함수를 사용해 중단 가능한 작업을 작성합니다.
2. 코루틴 시작하기
코틀린에서 코루틴을 사용하려면 kotlinx.coroutines 라이브러리를 추가해야 합니다.
Gradle 설정:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
(1) 코루틴 기본 사용법
코루틴은 launch나 async와 같은 빌더를 사용해 실행합니다.
1) launch
launch는 결과를 반환하지 않는 코루틴을 실행합니다.
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000L) // 1초 대기 (비동기)
println("World!")
}
println("Hello,")
}
출력:
Hello,
World!
- delay는 현재 코루틴을 잠시 중단합니다.
- runBlocking은 메인 스레드에서 코루틴이 끝날 때까지 기다립니다.
2) async
async는 결과를 반환하는 코루틴을 실행합니다.
import kotlinx.coroutines.*
fun main() = runBlocking {
val result = async {
delay(1000L)
42 // 반환 값
}
println("Result: ${result.await()}") // 결과를 기다림
}
출력:
Result: 42
3. suspend 함수
delay와 같은 코루틴 함수는 suspend로 선언됩니다. suspend 함수는 다른 suspend 함수나 코루틴 블록에서만 호출할 수 있습니다.
suspend fun fetchData(): String {
delay(1000L)
return "Data loaded"
}
fun main() = runBlocking {
println(fetchData())
}
4. 코루틴 컨텍스트와 디스패처
코루틴은 실행 환경을 지정할 수 있습니다. 대표적으로 다음 세 가지 디스패처를 자주 사용합니다.
(1) Dispatchers.Default
CPU 집약적인 작업(연산)을 수행할 때 사용합니다.
launch(Dispatchers.Default) {
println("Running on Default")
}
(2) Dispatchers.IO
입출력 작업(파일, 네트워크)을 처리할 때 사용합니다.
launch(Dispatchers.IO) {
println("Running on IO")
}
(3) Dispatchers.Main
UI와 관련된 작업을 처리할 때 사용합니다(Android에서 주로 사용).
launch(Dispatchers.Main) {
println("Running on Main")
}
5. 구조화된 동시성(Structured Concurrency)
코루틴은 부모-자식 관계로 묶어 관리할 수 있습니다. 이를 통해 에러 처리를 안전하게 하고 리소스를 효율적으로 관리할 수 있습니다.
fun main() = runBlocking {
launch {
delay(1000L)
println("Task 1 completed")
}
launch {
delay(500L)
println("Task 2 completed")
}
println("Parent coroutine completed")
}
출력:
Parent coroutine completed
Task 2 completed
Task 1 completed
6. 에러 처리
코루틴에서 에러는 부모-자식 관계에 따라 전파됩니다. 예외를 안전하게 처리하려면 try-catch나 supervisorScope를 사용합니다.
try-catch 사용
fun main() = runBlocking {
try {
launch {
throw Exception("Error occurred")
}
} catch (e: Exception) {
println("Caught: ${e.message}")
}
}
7. 예제: 비동기 데이터 로드
suspend fun fetchDataFromServer(): String {
delay(1000L) // 서버에서 데이터를 가져오는 시뮬레이션
return "Server Data"
}
suspend fun fetchDataFromDatabase(): String {
delay(500L) // 데이터베이스에서 데이터를 가져오는 시뮬레이션
return "Database Data"
}
fun main() = runBlocking {
val serverData = async { fetchDataFromServer() }
val databaseData = async { fetchDataFromDatabase() }
println("Loaded: ${serverData.await()} and ${databaseData.await()}")
}
출력:
Loaded: Server Data and Database Data
728x90
반응형
'프로그래밍 언어 > Kotlin' 카테고리의 다른 글
[Kotlin] 8. 코틀린 DSL(Domain-Specific Language) 소개와 작성 방법 (0) | 2024.11.25 |
---|---|
[Kotlin] 6. 코틀린 확장 함수와 표준 라이브러리 활용 (0) | 2024.11.23 |
[Kotlin] 5. 컬렉션과 함수형 프로그래밍 (1) | 2024.11.22 |
[Kotlin] 4. 클래스와 객체 (0) | 2024.11.20 |
[Kotlin] 3. 조건문과 반복문 (0) | 2024.11.19 |