[Kotlin] Coroutines

sundays·2022년 11월 24일
0

kotlin

목록 보기
10/19

코루틴

  • 멀티태스킹을 하면서 가벼운 스레드라고 불림
  • 스택을 가지지 않는다
  • 문맥 교환(Context Switching)이 없다
  • 루틴을 일시 중단을 하여 제어

kotlinx.coroutines

common

  • launch / async : 코루틴 빌더
  • job / Deferred : cancellation 지원을 위한 기능
  • Dispatchers : Default는 백그라운드 코루틴을 위한 것이고 Main은 android나 Swing, JavaFx, IO 를 위해 사용
  • delay / yield : 상위 레벨 지연 함수
  • Channel / Mutex : 통신과 동기화를 위한 기능
  • coroutineScope / supervisorScope : 범위 빌더
  • select : 표현식 지원

core

  • CommonPool : 코루틴 컨텍스트
  • produce / actor : 코루틴 빌더

코루틴 빌더

launch

  • 일단 실행하고 잊어버리는(fire-and-forget) 형태의 코루틴으로 메인 프로그램과 독립되 실행할 수 있다
  • 기본적으로 즉시 실행하며 블록 내의 실행결과는 반환하지 않는다
  • join을 통해 상위 코드가 종료되지 않고 완료를 기다리게 할 수 있다

async

  • 비동기 호출을 위해 만든 코루틴으로 결과나 예외를 반환한다
  • 실행결과는 Deffered<T>를 통해 반환하며 await를 통해 받을 수 있다
  • await 는 작업이 완료될 때까지 기다리게 된다.

예시

import kotlinx.coroutines.*

fun main() { // 메인 스레드의 문맥
    GlobalScope.launch { // 새로운 코루틴을 백그라운드에서 실행
        delay(1000L) // 1초의 넌블로킹 지연
        println("world") // 지연 후 출력
    }
    println("Hello") // main 스레드가 코루틴이 지연되는 동안 계속 실행
    Thread.sleep(2000L) // main 스레드가 jvm에서 바로 종료되지 않게 2초 기다림
}

// RETURN
// Hello
// world
  • main 스레드 안에서는 2초를 기다리게 하지만 이때는 메인 호출 스레드를 블록 시킵니다.
  • delay()는 일시 중단 되어 있는 사이에 다른 루틴을 블로킹 하지 않으므로 다른 일을 할 수 있게 하는 것
  • 스레드처럼 스택을 독립적으로 가진 요소는 아닙니다
  • 지연 함수(delay)는 반드시 코루틴 안에서만 사용해야 합니다

suspended 함수

  • delay()의 경우 일시 중단
  • 반드시 코루틴 안에서만 실행 된다

delay() 의 선언부

// kotlinx-coroutines-core 의 DelayKt.class 일부
public suspend fun delay(timeMillis: kotlin.Long) : kotlin.Unit { /* compiled code */}
  • suspend 함수를 코루틴 블록 외에 사용하면 오류가 남

사용자 함수에 suspend 적용

suspend fun doSomething() {
    print("DoSomething")
}
  • 컴파일러는 suspend가 붙은 함수를 자동적으로 추출해 Continuation 클래스로 부터 분리된 루틴을 만든다
  • 이러한 함수를 사용하기 위해 코루틴 빌더인 launch와 async에서 이용할 수 있다

Job 객체

  • 코루틴의 생명주기를 관리하며 생성된 작업들은 부모-자식 관계를 가질 수 있다
  • 규칙
    • 부모가 취소 되거나 실행 실패하면 하위 자식들은 모두 취소된다
    • 자식의 실패는 그 부모에 전달되며 부모 또한 실패한다 (다른 모든 자식도 취소됨)
  • SupervisorJob
    • 자식의 실패가 그 부모나 다른 자식에 전달되지 않으므로 실행을 유지할 수 있다

Join() 결과 기다리기

  • job객체의 join()을 사용해 완료를 기다릴 수 있다
    • lauch에서 반환값을 받으면 job객체가 되기 때문에 이것을 이용해 main 메서드에서 join()을 호출할 수 있다

job의 상태

  • New
  • Active (기본값 상태)
  • Completing
  • Canceling
  • Cancelled (최종상태)
  • Completed (최종상태)

코루틴의 중단과 취소

중단 (코루틴 코드 내)

  • delay(시간) - 일정 시간을 지연하며 중단
  • yield() - 특정 값을 산출하기 위해 중단

취소 (코루틴 외부에서)

  • Job.cancel() : 지정된 코루틴 작업을 즉시 취소
  • Job.cancelAndJoin() : 지정된 코루틴 작업을 취소 (완료시 까지 기다림)
  • 기본적으로 부모 자식 관계에 적용될 수 있으며 부모 블로이 취소되면 모든 자식 코루틴이 취소된다

Reference

  • 코틀린 프로그래밍 - 황영덕
profile
develop life

0개의 댓글