Job 객체
val job = launch(start = CoroutineStart.LAZY) { // ... } delay(1000L) job.start() // start 하지 않으면 코루틴이 시작되지 않음
job.cancel() // 돌던 job 을 취소시킴
val job1 = launch { // ... delay(1000) // ... } job1.join() val job2 = launch { // ... delay(1000) // ... }
join()
이 없었다면 전체 수행시간을 1초 내외지만 (job1, job2가 거의 동시에 실행되므로)join()
이 있다면 job1 이 끝날 때 까지 대기했다가 job2 를 실행한다.객체 활용 정리
start()
: 시작 신호cancel()
: 취소 신호join()
: 코루틴이 완료될 떄까지 blocking
Deferred
객체를 반환함val job: Deferred = async {
3 + 5
}
val result = job.await() // 8
Deffered
Job
객체를 상속 받았기 때문에 동일한 기능들이 있음
- start(), cancel(), join()
await()
가 추가로 있음
- async 의 결과를 가져오는 함수
fun main(): Unit = runBlocking {
val time = measureTimeMillis {
val job1 = async { apiCall() }
val job2 = async { apiCall() }
println(job1.await() + job2.await())
}
println(time) // 1049ms
}
suspend fun apiCall(): Int {
delay(1000L)
return 1
}
주의 사항
CoroutineStart.LAZY
옵션을 사용할 경우await()
함수를 호출했을 때 계산 결과를 계속 기다리게된다.
전통적인 동기식 방식
sequenceDiagram participant MainThread participant APICall1 participant APICall2 participant APICall3 MainThread->>APICall1: Start API Call 1 Note right of APICall1: API Call 1 processing... APICall1-->>MainThread: API Call 1 complete MainThread->>APICall2: Start API Call 2 Note right of APICall2: API Call 2 processing... APICall2-->>MainThread: API Call 2 complete MainThread->>APICall3: Start API Call 3 Note right of APICall3: API Call 3 processing... APICall3-->>MainThread: API Call 3 complete Note over MainThread: All API calls completed sequentially코루틴 async 를 사용했을 때
sequenceDiagram participant MainThread participant APICall1 participant APICall2 participant APICall3 MainThread->>APICall1: Start API Call 1 Note right of APICall1: API Call 1 processing... MainThread->>APICall2: Start API Call 2 Note right of APICall2: API Call 2 processing... MainThread->>APICall3: Start API Call 3 Note right of APICall3: API Call 3 processing... APICall1-->>MainThread: API Call 1 complete APICall2-->>MainThread: API Call 2 complete APICall3-->>MainThread: API Call 3 complete Note over MainThread: All API calls completed asynchronously
- runBlocking의 사용:
runBlocking
은 코루틴 스코프를 만들고, 이 스코프 내에서 실행되는 모든 코루틴이 완료될 때까지 현재 스레드를 차단합니다. 이는 주로 메인 함수나 테스트 코드에서 사용됩니다. 프로덕션 코드에서는runBlocking
을 남용하지 않는 것이 좋습니다.- Job 객체: 코루틴의 생명주기를 제어할 수 있는 핸들러 역할을 합니다. 이를 통해 코루틴을 시작(start), 취소(cancel), 대기(join)할 수 있습니다.
- CoroutineStart.LAZY: 코루틴을 지연 시작합니다. 즉,
start
메서드를 호출하거나await
또는join
이 호출될 때까지 시작되지 않습니다.- 비동기 API 호출:
async
를 사용하여 비동기적으로 여러 API를 호출하고, 결과를 기다리지 않고 다음 작업을 수행할 수 있습니다. 이는 I/O 작업의 효율성을 높이는 데 유용합니다.- 코루틴 컨텍스트와 디스패처: 코루틴은 컨텍스트와 디스패처를 통해 실행되는 스레드를 결정합니다. 예를 들어,
Dispatchers.IO
는 I/O 작업을 위한 디스패처이고,Dispatchers.Main
은 UI 작업을 위한 디스패처입니다. 이후에 다룸