Kotlin/코틀린 코루틴의 정석

[Kotlin 코루틴] 코루틴 빌더와 Job 정리

꾸준함. 2024. 11. 8. 01:59

코루틴 빌더와 Job 객체 개요

  • 코루틴을 생성하는 데 사용하는 함수
    • ex) runBlocking, launch

 

  • 모든 코루틴 빌더 함수는 코루틴을 만들고 코루틴을 추상화한 Job 객체를 생성
  • 코루틴은 일시 중단할 수 있는 작업으로 실행 도중 일시 중단된 후 이후 이어서 실행될 수 있음
    • 코루틴을 추상화한 Job 객체는 이에 대응해 코루틴을 제어할 수 있는 함수와 코루틴의 상태를 나타내는 상태 값들을 외부에 노출시킴

 

 

 

부연 설명

  • launch 함수 호출 시 코루틴 생성
  • Job 객체가 생성되고 반환되는 것을 확인 가능

 

join을 사용한 코루틴 순차 처리

  • Job 객체는 순차 처리가 필요한 상황을 위해 join 함수를 제공
  • join 함수를 통해 먼저 처리되어야 하는 코루틴의 실행이 완료될 때까지 호출부의 코루틴을 일시 중단하도록 만들 수 있음

 

 

 

부연 설명

  • runBlocking 코루틴이 updateTokenJob.join()을 호출하면 runBlocking 코루틴은 updateTokenJob 코루틴이 완료될 때까지 일시 중단
    • join 함수를 호출하지 않을 경우 `토큰 업데이트 작업`과 `네트워크 요청 작업`이 병렬로 동시에 실행됐음

 

joinAll을 사용한 코루틴 순차 처리

  • 실제 개발에서는 서로 독립적인 여러 코루틴을 병렬로 실행한 뒤 실행한 요청들이 모두 끝날 때까지 대기한 뒤 다음 작업을 진행하는 것이 효율적
    • 이를 위해 Job 객체는 joinAll 함수를 제공하며 joinAll 함수는 가변 인자로 Job 타입의 객체를 받은 후 각 Job 객체에 대해 모두 join 함수를 호출하는 것이 전부

 

 

CoroutineStart.LAZY를 통해 코루틴 지연

  • launch 함수를 사용해 코루틴을 생성하면 유휴 쓰레드가 있는 경우 곧바로 실행되지만 나중에 실행돼야 할(지연 시작) 코루틴을 미리 생성해야 하는 케이스도 존재
  • 코루틴을 지연 시작하기 위해서는 launch 함수의 start 인자로 CoroutineStart.LAZY를 넘겨 코루틴에 지연 시작 옵션을 적용해야 함
    • 지연 코루틴은 명시적으로 실행을 해줘야 함
    • Job 객체의 start 함수를 명시적으로 호출해야 함

 

 

코루틴 취소하기

  • 코루틴 실행 도중 코루틴을 실행할 필요가 없어질 경우 즉시 취소해야 함
    • 필요 없는 코루틴을 실행되도록 두면 코루틴을 계속해서 쓰레드를 점유하며 성능 저하를 유발할 수 있음

 

  • 위 문제를 해결하기 위해 Job 객체는 코루틴을 취소할 수 있는 cancel 함수를 제공

 

1. cancel 함수를 사용해 Job 취소하기

 

 

2. cancelAndJoin을 사용한 순차 처리

  • Job 객체에 cancel 함수를 호출하면 코루틴은 즉시 취소되는 것이 아니라 Job 객체 내부의 취소 확인용 flag 변수를 `취소 요청됨`으로 변경함으로써 코루틴이 취소돼야 한다는 것만 알림
    • 이후 미래의 어느 시점에 코루틴의 취소가 요청됐는지 체크하고 취소됨

 

  • 앞서 Job 객체의 join 함수를 사용하면 코루틴을 순차 처리할 수 있었던 것처럼 cancelAndJoin 함수를 사용하면 취소에 대한 순차 처리가 가능해짐

 

 

3. 코루틴의 취소가 확인되는 시점

  • 코루틴은 일반적으로 실행 대기 시점이나 일시 중단 시점에 취소를 확인한 후 취소됨
  • while 문을 통해 무한 루프를 실행할 경우 일시 중단 지점이 없기 때문에 일시 중단이 일어날 수 없음
  • 위 문제를 해결할 수 있는 세 가지 방법 존재
    • delay를 사용한 취소 확인
    • yield를 사용한 취소 확인
    • CoroutineScope.isActive를 사용한 취소 확인

 

3.1 delay를 사용한 취소 확인

  • delay 함수는 일시 중단 함수(suspend fun)로 선언돼 특정 시간만큼 호출부의 코루틴을 일시 중단시킴
  • 앞서 언급했듯이 코루틴은 일시 중단되는 시점에 코루틴의 취소를 확인
  • 목적은 달성하지만 불필요하게 작업을 일시 중단시키므로 성능 저하 유발함

 

 

3.2 yield를 사용한 취소 확인

  • yield 함수가 호출되면 코루틴은 자신이 사용하던 쓰레드를 양보함
  • 쓰레드 사용을 양보한다는 것은 쓰레드 사용을 중단한다는 뜻이므로 yield를 호출함으로써 목적 달성 가능
  • 하지만 yield 함수 또한 while 문을 한 번 돌 때마다 쓰레드 사용이 양보되면서 일시 중단되는 문제가 발생해 비효율적

 

 

3.3 CoroutineScope.isActive를 사용한 취소 확인

  • CoroutineScope는 코루틴이 활성화됐는지 확인할 수 있는 Boolean 타입의 프로퍼티인 isActive를 제공함
    • 코루틴에 취소가 요청되면 isActive 프로퍼티의 값은 false로 바뀜

 

  • 위 방법을 사용하면 코루틴이 잠시 멈추지도 않고 쓰레드 사용을 양보하지 않으면서 계속해서 작업을 할 수 있어 효율적

 

 

코루틴의 상태와 Job의 상태 변수

  • 코루틴은 6가지 상태를 가짐
    • 생성 (New)
    • 실행 중 (Active)
    • 실행 완료 중 (Completing)
    • 실행 완료 (Completed)
    • 취소 중 (Cancelling)
    • 취소 완료 (Cancelled)

 

  • 이 중 `실행 완료 중` 상태는 이번 게시글 말고 이후 게시글에 다룰 예정

 

https://medium.com/@ramesh_aran86/kotlin-coroutines-concepts-769f2b598be9

 

1. Job 객체에서 외부로 공개하는 코루틴의 상태 변수

  • Job 객체의 상태 변수들은 코루틴의 상태마다 변화함
  • 외부로 공개하는 코루틴의 상태 변수는 총 세 가지로 모두 Boolean 타입
    • isActive
    • isCancelled
    • isCompleted

 

1.1 isActive

  • 코루틴이 활성화돼 있는지의 여부 확인 가능
    • 코루틴이 활성화돼 있으면 true
    • 활성화돼 있지 않으면 false

 

1.2 isCancelled

  • 코루틴이 취소 요청됐는지의 여부 확인 가능
    • 코루틴에 취소 요청되면 true

 

  • 앞서 언급했다시피 isCancelled가 참이더라도 즉시 취소되는 것은 아님

 

1.3 isCompleted

  • 코루틴 실행이 완료됐는지의 여부 확인 가능
    • 코루틴의 모든 코드가 실행 완료되면 true 반환
    • 혹은 취소 완료되면 true 반환
    • 실행 중인 상태에서는 false

 

2. 코루틴 상태

 

2.1 생성 (New)

  • 코루틴 빌더를 통해 코루틴을 생성하면 코루틴은 기본적으로 생성 상태
  • 보통 자동으로 `실행 중` 상태로 넘어감
    • 앞서 언급한 CoroutineStart.LAZY를 start 인자로 넘기면 실행 중 상태로 바로 안 바뀜

 

 

2.2 실행 중 (Active)

  • 코루틴이 실제로 실행 중일 때뿐만 아니라 실행된 후 일시 중단된 때도 실행 중 상태


 

2.3 실행 완료 (Completed)

  • 코루틴의 모든 코드가 실행 완료된 상태


 

2.4 취소 중 (Cancelling)

  • Job.cancel() 등을 통해 코루틴에 취소가 요청됐을 경우 최소 중 상태로 넘어감
  • 아직 취소된 상태가 아니어서 코루틴은 계속해서 실행됨

 

 

2.5 취소 완료 (Cancelled)

  • 코루틴의 취소 확인 시점에 취소가 확인된 경우 취소 완료 상태로 전환
  • 해당 상태에서는 코루틴은 더 이상 실행되지 않음

 

 

3. 코루틴 상태 정리

 

코루틴 상태 isActive isCancelled isCompleted
생성 (New) false false false
실행 중 (Active) true false false
실행 완료 (Completed) false false true
취소 중 (Cancelling) false true false
취소 완료 (Cancelled) false true true

 

참고

코틀린 코루틴의 정석 (조세영 저)

반응형