코루틴 #3 - suspend Function (중단함수)
Coroutine 이전 글
기본 순차 실행 (Sequential by Default)
기본적으로 Code & Function은 순차적(Sequential)으로 수행
이런 개념은 Coroutine 내부에서도 동일하게 적용됩니다
일정시간 delay 후 Integer 값을 반환하는 두개의 suspend(중단) 함수 생성
suspend fun testOne(): Int {
delay(1000) // 1초 대기
return 20 // 20 반환
}
suspend fun testTwo(): Int {
delay(2000) // 2초 대기
return 40 // 40 반환
}
두 개의 suspend함수 호출 후 걸리는 시간을 보기위한 예시
fun main(args: Array<String>) = runBlocking<Unit> {
val time = measureTimeMillis { // measureTimeMillis 블록 내부 실행에 걸리는 시간 반환
val one = testOne() // suspend 함수 1
val two = testTwo() // suspend 함수 2
println("Result is one [$one] two [$two]")
}
println("Completed in ${time}ms") // 총 걸린 시간 표시
}
위 예시 코드는 두 개의 중단함수 testOne(), testTwo()를 순차적으로 호출하여, 반환된 값을 더하여 출력하는 예시입니다
출력 결과
Result is one [20] two [40]
Completed in 3016ms
결과에서 총 수행시간을 보면 함수가 순차적으로 수행되었기 때문에 3016ms가 걸렸습니다.
먼저 testOne()이 1000ms대기 후 완료되고, 그 다음 testTwo()가 2000ms를 Delay하기 때문에 그렇습니다
async 통한 동시 수행 (Concurrent using async)
만약 위의 두 중단함수가 서로 인과관계(의존성)을 갖지 않는다면, 두 개의 함수를 동시에 수행시 더 빠른 동작을 구현 가능
launch{} 와 async{}는 동일한 컨셉이지만, return 객체의 차이가 있는 코루틴 빌더입니다.
launch{} -> Job return
async{} -> Deferred<T> return
Job은 launch로 생성된 코루틴의 상태를 관리하는 용도로 사용하고 결과값을 리턴받을 수 없으나,
Deferred는 async블럭 내 수행된 결과를 원하는 시점에 return받을 수 있다는 큰 차이가 있습니다.
Deferred는 job을 상속받아 구현되었기 때문에 Job의 기능을 사용할 수 있습니다.
fun main(args: Array<String>) = runBlocking<Unit> {
val time = measureTimeMillis {
val one = async { testOne() }
val two = async { testTwo() }
println("Result is one [${one.await()}] two [${two.await()}]")
}
println("Completed in $time ms")
}
출력결과
Result is one [20] two [40]
Completed in 2059ms
두 개의 작업이 동시에 실행되었기 때문에 testTwo()의 delay(2000)을 마지막으로 모든 실행이 종료된 걸 확인 가능
async의 지연 실행 (Lazily started async)
launch와 마찬가지로 async도 start 파라미터에 CoroutineStart.LAZY 값을 할당해서 실행지연 가능
LAZY옵션이 설정된 코루틴은 start() 또는 join()/await() 함수가 호출되는 시점에 실행이 됩니다.
fun main(args: Array<String>) = runBlocking<Unit> {
val time = measureTimeMillis {
val one = async(start = CoroutineStart.LAZY) { testOne() }
val two = async(start = CoroutineStart.LAZY) { testTwo() }
delay(4000)
// LAZY 설정 코루틴 실행 시작
one.start()
two.start()
println("Result is one [${one.await()}] two [${two.await()}]")
}
println("Completed in $time ms")
}
실행결과
Result is one [20] two [40]
Completed in 6020ms
걸린 시간을 보면 6020ms로 기존 2059ms에 비해 4000ms가 길어졌다는 걸 보면
testOne() 과 testTwo() 중단함수의 실행이 delay(4000) 이후에 시작되고 반환되는 것을 보여줍니다.
LAZY 설정 코루틴은 꼭 start()가 아닌 await()으로도 대체 가능하기 때문에 위 예시에서 one.start() two.start()는 생략이 가능합니다