delay
함수를 1초간 호출 하므로 약2초의 시간이 측정됨.fun main() = runBlocking {
val times = measureTimeMillis {
val one = doSomethingUsefulOne()
val two = doSomethingUsefulTwo()
println("The answer is ${one + two}")
}
println("Completed in $times ms")
}
suspend fun doSomethingUsefulOne(): Int {
delay(1000)
return 13
}
suspend fun doSomethingUsefulTwo(): Int {
delay(1000)
return 29
}
// The answer is 42
// Completed in 2017 ms
async
함수를 사용할 수 있음.
async
는 launch
와 같지만, 다른점은
launch
: 결과값을 전달하지 않는 Job
을 리턴함.async
: 결과값을 반환하는 Deffered
를 리턴함.
await
함수를 사용하여 결과값을 얻을 수 있음.Deffered
는 결과값을 수신하는 비동기 작업임. 이는 Job
의 모든 속성을 가지고 있음.
fun main() = runBlocking {
val times = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $times ms")
}
// The answer is 42
// Completed in 1015 ms
async
함수의 파라미터 값을 CoroutineStart.LAZY로 설정할 수 있음.
CoroutineStart.LAZY
로 시작된 async
는 자동으로 시작되지 않음.async
를 lazy하게 만듦. 즉, 개발자가 언제 실행하게 할 것인지 트리거할 수 있는 제어 권한이 주어짐.
start
가 트리거 역할을 함.
fun main() = runBlocking {
val time = measureTimeMillis {
val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
one.start()
two.start()
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
}
// The answer is 42
// Completed in 1015 ms
async
를 lazy하게 실행할 때, 코루틴은 즉시 실행되지 않음.
start
, await
)이 호출되어야 코루틴이 실행됨.start
를 사용하지 않고, await
만 사용한 경우 이는 순차적으로 처리됨.
await
은 코루틴을 시작하고 완료를 기다리기 때문.GlobalScope
를 참조하는 async
코루틴 빌더를 사용해 비동기 스타일의 함수를 정의할 수 있음.
GlobalScope
사소하지 않은 역효과를 일으킬 수 있음. → 사용을 지양하자.
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulOneAsync() = GlobalScope.async {
doSomethingUsefulOne()
}
suspend fun concurrentSum(): Int = coroutineScope {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
one.await() + two.await()
}
fun main() = runBlocking {
val times = measureTimeMillis {
println("The answer is ${concurrentSum()}")
}
println("Completed in $times ms")
}
// The answer is 42
// Completed in 1018 ms
위 코드처럼 coroutineScope
로 함수를 작성하면 concurrentSum
함수 내부에서 예외가 발생 되었을 때, 스코프 내부에서 실행된 모든 코루틴들이 취소됨.