선생님, 개발을 잘하고 싶어요.

코루틴 정리하기 본문

개발/android 개발

코루틴 정리하기

알고싶은 승민 2020. 8. 2. 16:35

도입

코틀린 문서: https://kotlinlang.org/docs/reference/coroutines-overview.html

안드로이드 문서: https://developer.android.com/kotlin/coroutines

 

실무에서 프로그램을 작성하면 언제나 멀티 스레드 작업을 하게 된다. 하지만 복잡하고 타이밍 문제가 속출하는 멀티 스레드를 기본 제공되는 API로 구현하는 것은 끔찍한 일이다.

 

그래서 Task 같은 인터페이스로 추상화된 개념으로 작업을 하거나, RxJava 라이브러리를 추가해서 멀티 스레드 작업을 처리했다.

 

그런데 기존 방식의 문제는 간단한 구현과 관련된 엄청난 러닝 커브와 직관적이지 않은 형태, 그리고 많은 보일러 플레이트 코드가 문제가 됐다.

다른 언어 (C#, ES)등 최신 언어 스펙에는 async, await라는 키워드를 별도로 제공해서 이러한 멀티 스레드 작업, 비동기 작업을 직관적으로 만들어 주었는데, 이와 비슷하지만 더 범용적으로 쓰일 수 있는 개념을 Kotlin이 가지고 나왔다.

 

바로 코 루틴이다. 공식 문서와 안드로이드 지원 문서를 함께 보며 실제 개발에 사용해 본다면, 그 간단함을 느낄 수 있다.

 

핵심 클래스

Coroutine Builder

코루틴 블락을 생성하는 방법

  • launch: non-blocking
  • async: non-blocking
  • runBlocking: blocking

Job

코 루틴의 실행을 추상화한 객체

  • 취소 가능하다.
  • 생명 주기를 가진다.

Job의 취소

job.cancel()을 시도하면 취소된다.

    CancellationException이 발생하면서 작업이 중단된다.

withContext(NonCancellable) {...}를 이용해서 취소 불가능한 코 루틴을 만들 수 있다.

Scope

Job이 실행되는 환경

scope.cancel()을 사용하면 scope가 관리하는 모든 작업을 취소할 수 있다.

 

android와 같은 환경에서 생명주기에 맞게 custom scope를 생성해서 사용할 수 도 있다.

https://developer.android.com/topic/libraries/architecture/coroutines

Lifecycle, ViewModel, LiveData에 대한 코루틴 지원이 공식 포함되어있다

Suspend Function

함수 본체가 코 루틴으로 동작하는 함수

외부에서 보기에 단일 값을 스레딩 작업을 통해 받아오는 것으로 이해될 수 있다.

  • 코루틴 블록에서만 사용할 수 있다.
  • 내부 동작하는 스레드는 외부에서 지정할 수 있다. (기본)
  • 내부 동작하는 스레드를 강제 지정할 수 있다. (withContext)

실행 흐름

  • 기본 적으로 순차적으로 진행된다.
  • async 블락으로 시작하면 비동기적으로 실행된다.
    • Deferred <T> 타입의 Job 하위 객체가 반환된다.
    • deferred.await()를 호출하면 비동기 작업을 기다리고, 값을 꺼내온다.
    • async block을 사용하여 suspending 비슷한 함수를 만드는 방법은 비 권장되는 방법이다.
      • 로컬 에러 처리가 어렵기 때문이다.

Dispatcher

코 루틴이 실행될 때 사용될 thread 환경을 정의한다.

  • 특정 스레드를 지정
  • 스레드 풀을 지정

ex)

  • 안드로이드 UI 스레드 동작을 지정할 때 Disptachers.Main
  • 네트워크 스레드 동작을 지정할 때 Dispatchers.IO

각 Coroutine Builder의 생성 인자로 넘겨줄 수 있다.

GlobalScope.launch(Disptachers.Main) { ui.update() }

코 루틴은 RxJava의 Single 인터페이스의 의미랑 유사하다고 느껴진다.

혹은 Task <T> 인터페이스로 제공되는 비동기 작업과 유사하다.

코 루틴을 사용하면 언어 차원에서 별도의 의존성 없이 비동기적으로 실행되는 함수를 선언할 수 있다.

따라서 Domain객체를 정의하는데 의존성 없이 오로지 언어 스펙만으로 작성할 수 있는 표현성이 늘어났다.

Comments