728x90
Suspend
- 비동기 실행을 위한 중단 지점
- 잠시 중단하고, 언젠가 다시 시작 즉 일시중단이 가능하도록 하게 하는 키워드
코루틴 Suspend 함수는 구성 및 접근법이 다양함
순차적 실행
fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
val one = doOne();
val two = doTwo();
println("결과 : ${one + two}")
}
println("완료 ${time}")
}
suspend fun doOne(): Int {
println("첫번째 함수 시작")
delay(1000L)
return 1;
}
suspend fun doTwo(): Int {
println("두번째 함수 시작")
delay(1000L)
return 2;
}
// 첫번째 함수 시작
// 두번째 함수 시작
// 결과 : 3
// 완료 2024
- 코루틴 내부 코드는 일반 코드처럼 순서대로 실행
- 비동기 연산을 순차적으로 실행함
동시 실행
fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
val one = async { doUseOne() }
val two = async { doUseTwo() }
println("결과 : ${one.await() + two.await()}")
}
println("완료 ${time}")
}
suspend fun doUseOne(): Int {
println("첫번째 함수 시작")
delay(1000L)
return 1;
}
suspend fun doUseTwo(): Int {
println("두번째 함수 시작")
delay(1000L)
return 2;
}
// 첫번째 함수 시작
// 두번째 함수 시작
// 결과 : 3
// 완료시간 : 1040
- 동시 수행시 async를 사용
- async는 launch랑 비슷한 코루틴 빌더, deffered(결과값을 나중에 돌려줌) 객체를 반환함
- await() 함수를 사용하면 비동기 처리 완료됐을 때 결과값을 반환받을 수 있음
- 예제를 확인해보면 완료시간이 2초가아니라 1초만에 처리함
지연 실행
fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
val one = async(start = CoroutineStart.LAZY) { doUseOne() }
val two = async(start = CoroutineStart.LAZY) { doUseTwo() }
//one.start()
//two.start()
//스타트를 하지 않은 경우 완료시간이 2초이지만, 할경우 1초만에 처리됨
println("결과 : ${one.await() + two.await()}")
}
println("완료시간 : ${time}")
}
suspend fun doUseOne(): Int {
println("첫번째 함수 시작")
delay(1000L)
return 1;
}
suspend fun doUseTwo(): Int {
println("두번째 함수 시작")
delay(1000L)
return 2;
}
// 첫번째 함수 시작
// 두번째 함수 시작
// 결과 : 3
// 완료시간 : 2033
- async로 생성된 코루틴은 start = CoroutineStart.Lazy 옵션을 주게되는 경우 지연실행이 됨
- suspending 함수가 사용되는 경우 lazy대신 CoroutineStart.Lazy 옵션 사용
- start를 선언할 경우 동시에 처리 실행하기 때문에 완료시간이 1초 걸림
Async-style 함수형태 실행
fun main() {
val time = measureTimeMillis {
val one = doUsefulOneAsync()
val two = doUsefulTwoAsync()
runBlocking {
println("결과 : ${one.await() + two.await()}")
}
}
println("완료시간 : ${time}")
}
fun doUsefulOneAsync() = GlobalScope.async { doUsefulOne() }
fun doUsefulTwoAsync() = GlobalScope.async { doUsefulTwo() }
suspend fun doUsefulOne(): Int {
println("첫번째 함수 시작")
delay(1000L)
return 1;
}
suspend fun doUsefulTwo(): Int {
println("두번째 함수 시작")
delay(1000L)
return 2;
}
- GlobalScope 범위에서 async 빌더를 통하여 비동기적으로 작동하는 함수를 정의가 가능함
- async함수는 suspending이 아니라 어디서든지 사용가능하나, 실제동작은 비동기로 이루어짐
- 이방식은 권장하지 않음, async함수와 await사이에 excedption이 발생한 경우, 중단되었음에도 불구하고 연산을 수행하기 때문
Structured 동시성 / 비동기 실행
fun main() = runBlocking {
val time = measureTimeMillis {
println("결과 : ${concurrentUse()}")
}
println("완료시간 : ${time}")
}
suspend fun concurrentUse(): Int = coroutineScope {
val one = async { getOne() }
val two = async { getTwo() }
// delay(10)
// kotlin.io.println("예외")
// throw Exception()
// 예외발생시 함수 실행이 중단됨
one.await() + two.await()
}
suspend fun getOne(): Int {
println("첫번째 함수 시작")
delay(1000L)
return 1;
}
suspend fun getTwo(): Int {
println("두번째 함수 시작")
delay(1000L)
return 2;
}
- 동시성 처리 함수를 coroutineScope안에서만 처리하도록 설정
- coroutineScope안에만 있기 때문에 예외발생시, 연산을 진행하지 않음
'KOTLIN' 카테고리의 다른 글
[KOTLIN] CONTEXT / DISPATCHER (0) | 2022.06.15 |
---|---|
[KOTLIN] CANCELLATION (취소) (0) | 2022.06.09 |
[KOTLIN] 코루틴 (0) | 2022.06.01 |
[KOTLIN] NULL SAFTY / NULL 처리방법 (0) | 2022.05.30 |
[KOTLIN] LATEINIT / LAZY (0) | 2022.05.22 |