async
코루틴을 만드는 코루틴 빌더로 Deferred<T>
객체를 반환하고 비동기 작업 수행에 대한 결과값을 반환하기 때문에 이 결과값을 받아서 다른 작업에 사용할 때 주로 사용한다.
await()
Deferred
객체는 결과값이 있는 비동기 작업을 수행하기 위해 결과값이 없는 Job
을 확장하는 인터페이스로 Job
의 모든 특성을 가지고 있다.
Deferred
에서 결과값을 받기 위해 await()
을 호출하면 실행되고 있는 코루틴은 Deferred
의 결과값을 대기하고 수신되면 반환한다.
import kotlinx.coroutines.*
fun main() = runBlocking {
println("Start")
println("${deferred1.await()} ${deferred2.await()}")
// or println("${awaitAll(deferred1, deferred2)}")
println("End")
}
val deferred1: Deferred<String> = GlobalScope.async {
var i = 0
while (i < 3) {
delay(1000)
i++
}
"Result1"
}
val deferred2: Deferred<String> = GlobalScope.async {
var i = 0
while (i < 3) {
delay(1000)
i++
}
"Result2"
}
// Start
// Result1 Result2
// End
start()
코루틴 빌더 async
의 start()
파라미터에 CoroutineStart.Lazy
를 할당하면 해당 코루틴을 호출하는 시점에 실행되도록 할 수 있지만, join()
과 다르게 start()
는 실행만 시키고 종료를 대기하지 않는다. (non-blocking
)
import kotlinx.coroutines.*
// deferred.start()
fun main() = runBlocking {
println("Start")
deferred.start()
println("End")
}
val deferred: Deferred<String> = GlobalScope.async(start = CoroutineStart.LAZY) {
var i = 0
while (i < 3) {
delay(1000)
i++
}
"Result"
}
// Start
// End
// Result
import kotlinx.coroutines.*
// deferred.join()
fun main() = runBlocking {
println("Start")
deferred.join()
println("End")
}
val deferred: Deferred<String> = GlobalScope.async(start = CoroutineStart.LAZY) {
var i = 0
while (i < 3) {
delay(1000)
i++
}
"Result"
}
// Start
// Result
// End
Concurrent Using Async (Async 동시 수행)
2개의 함수 실행 시 서로 의존성을 갖지 않는다면 순차 수행보다 동시 수행 시 더 빠른 동작 구현 가능하며 async
사용하여 이를 구현할 수 있다.
import kotlinx.coroutines.*
fun main() = runBlocking { // 순차 수행
val time = measureTimeMillis {
val test1 = test1()
val test2 = test2()
}
println("Completed ${time}ms")
}
suspend fun test1(): String {
delay(1000)
return "Test1"
}
suspend fun test2(): String {
delay(2000)
return "Test2"
}
// Completed 3020ms
import kotlinx.coroutines.*
fun main() = runBlocking { // 동시 수행
val time = measureTimeMillis {
val test1 = async { test1() }
val test2 = async { test2() }
}
println("Completed ${time}ms")
}
suspend fun test1(): String {
delay(1000)
return "Test1"
}
suspend fun test2(): String {
delay(2000)
return "Test2"
}
// Completed 2039ms