티스토리 뷰
이 요약은 https://youtu.be/Lpieg1zrKdg 다음 영상을 보고 요약한 개념입니다.
- 여러 개의 루틴을 동시에 실행하여 결과를 내고 싶다면 비동기 처리를 지원하는 코루틴을 사용한다.
- 코루틴은 메인이 되는 루틴과 별도로 진행이 가능한 루틴으로 코루틴은 개발자가 실행과 종료를 마음대로 제어할 수 있는 단위이다.
- 코루틴은 제어 범위와 실행 범위를 지정할 수 있다.
코루틴의 Scope
GlobalScope
프로그램 어디서나 제어, 동작이 가능한 기본 범위
CoroutineScope
특정한 목적의 Dispatcher를 지정하여 제어 및 동작이 가능한 범위
Coroutine의 dispatcher
- Dispatcher.Default : 기본적인 백그라운드에서 동작
- Dispatcher.IO : 네트워크나 디스크에 사용하는 I/O에 최적화 된 동작
- Dispatcher.Main : 메인(UI) 스레드에서 동작
launch와 async
- 생성된 Scope를 launch나 async 함수를 활용하여 새로운 Coroutine를 생성할 수 있다.
- launch와 async의 차이는 반환값이 있는지에 대한 여부
launch
launch {
for (i in 1..10) {
println(i)
}
}
- 반환값이 없는 Job 객체를 반환한다.
async
async {
var sum = 0
for (i in 1..10) {
sum ++
}
sum // 마지막 값이 반환된다.
}
- 반환값이 있는 Deffered 객체를 반환한다.
- aynch에 사용되는 람다 함수의 마지막 구문이 반환된다.
실습
import kotlinx.coroutines.* // coroutine 관련 라이브러리를 import
fun main() {
val scope = GlobalScope
scope.launch {
for (i in 1..5) {
println(i)
}
} // 이 scope에서 동작하기 전에
// main 함수가 끝나게 되어 코루틴도 같이 종료된다.
}
// 실행결과
// 결과값이 나오지 않는다.
- 코루틴은 제어되는 스코프 또는 프로그램 전체가 종료되면 함께 종료된다.
- 그래서 코루틴이 끝까지 실행되는 것을 보장하려면 일정한 범위에서 코루틴이 모두 실행될 때까지 잠시 기다려줘야 한다.
import kotlinx.coroutines.*
fun main() {
runBlocking {
launch {
for (i in 1..5) {
println(i)
}
}
}
}
// 실행결과
1
2
3
4
5
- runBlocking 블록을 만들고 이 블록 안에서 launch나 async를 직접 실행하면 코루틴이 종료될 때까지 메인 루틴을 잠시 대기시켜준다.
- 안드로이드에서 주의할 점은 메인 스레드에서 runBlocking을 걸어주면 ANR이 발생하여 앱이 강제 종료될 가능성이 있다.
루틴의 대기를 위한 추가적인 함수
밑의 세 함수들은 코루틴 내부 또는 runBlocking 블록과 같은 루틴의 대기가 가능한 구문 안에서만 사용이 가능하다.
1. delay(milisecond: Long)
- milisecond 단위로 루틴을 잠시 대기시키는 함수
2. join()
- Job.join() 형태로 쓰이며 Job의 실행이 끝날때까지 대기하는 함수
3. await()
- Defferred.await() 형태로 쓰이며 Defferred의 실행이 끝날때까지 대기하는 함수
- Defferred의 결과도 반환함
import kotlinx.coroutines.*
fun main() {
runBlocking {
val a = launch {
for (i in 1..5) {
println(i)
delay(10)
}
}
val b = async {
"async 종료"
}
println("async 대기")
println(b.await())
println("launch 대기")
a.join()
println("launch 종료")
}
}
// 실행결과
async 대기
1
async 종료
launch 대기
2
3
4
5
launch 종료
코루틴 도중 중단
cancel()
- 코루틴에 cancel을 걸어주면 다음 두 가지 조건이 발생하며 코루틴을 중단시킬 수 있다.
- 코루틴 내부의 delay() 함수 또는 yield() 함수가 사용된 위치까지 수행된 뒤 종료
- cancel() 로 인해 속성인 isActive가 false가 되므로 이를 확인하여 수동으로 종료
import kotlinx.coroutines.*
fun main() {
runBlocking {
val a = launch {
for (i in 1..5) {
println(i)
delay(10)
}
}
val b = async {
"async 종료"
}
println("async 대기")
println(b.await())
println("launch 취소")
a.cancel()
println("launch 종료")
}
}
// 실행결과
async 대기
1
async 종료
launch 취소
launch 종료
withTimeoutOrNull()
- 제한 시간 내에 수행되면 결괏값을 아닌 경우 null을 반환하는 함수
- join()이나 await()과 같은 blocking 함수
import kotlinx.coroutines.*
fun main() {
runBlocking {
val result = withTimeoutOrNull(50) {
for (i in 1..5) {
println(i)
delay(10)
}
"Finish"
}
println(result)
}
}
// 실행결과
1
2
3
null // timeOut 내에 수행될 수 없어 null이 출력된다.
출처
반응형
'Programming > 코틀린(Kotlin)' 카테고리의 다른 글
[Kotlin] Scope function 제대로 쓰자! (0) | 2022.10.30 |
---|---|
[코틀린] 15. Null 안전성과 예외 처리 (0) | 2021.05.04 |
[코틀린] 14. 컬렉션 타입과 람다 - 4. 요소 함수, 5. 정렬 함수 (0) | 2021.05.02 |
[코틀린] 14. 컬렉션 타입과 람다 - 2. 필터링 함수, 3. 매핑 함수 (0) | 2021.05.02 |
[코틀린] 14. 컬렉션 타입과 람다 - 1. 집합 연산 함수 (0) | 2021.05.02 |
댓글