멀티스레딩 및 콜백 기본 지침서

Kotlin으로 Android 앱 개발 과정에서는 멀티스레딩 개념 및 용어를 잘 알고 있다고 가정합니다. 따라서 여기서는 복습 차원에서 개념을 개략적으로 살펴봅니다.

휴대기기에는 프로세서가 있습니다. 오늘날 대부분의 기기에는 각기 프로세스를 동시에 실행하는 여러 하드웨어 프로세서가 있습니다. 이를 다중 처리라고 합니다.

운영체제는 프로세서를 더 효율적으로 사용하기 위해 애플리케이션이 프로세스 내에서 둘 이상의 실행 스레드를 만들도록 할 수 있습니다. 이를 멀티스레딩이라고 합니다.

이미지

동시에 여러 권의 책을 읽을 때 각 챕터 단위로 책을 번갈아 가며 읽다 보면 결국에는 모든 책을 다 읽을 수 있지만 정확히 동시에 두 권 이상의 책을 읽을 수 없는 것과 같다고 생각할 수 있습니다.

이러한 모든 스레드를 관리하려면 약간의 인프라가 필요합니다.

이미지

스케줄러는 우선순위와 같은 사항을 고려하며 모든 스레드가 실행되고 완료되도록 합니다. 책이 영원히 선반에 놓인 상태로 먼지가 쌓이지는 않지만 책이 너무 길거나 여유가 있는 경우 전달되기까지 시간이 걸릴 수 있습니다.

디스패처는 스레드를 설정합니다. 즉, 읽어야 하는 책을 보내고 독서가 진행될 컨텍스트를 지정합니다. 컨텍스트는 별도의 전문적인 독서실로 생각할 수 있습니다. 일부 컨텍스트는 사용자 인터페이스 작업에 가장 적합하고 일부는 입력/출력 작업을 처리하는 데 특화되어 있습니다.

사용자 대상 애플리케이션은 일반적으로 포그라운드에서 실행되는 기본 스레드를 가지고 있으며 백그라운드에서 실행될 수 있는 다른 스레드를 전달할 수 있다는 점만 알아두면 됩니다.

Android에서 기본 스레드는 UI에 관한 모든 업데이트를 처리하는 단일 스레드입니다. UI 스레드라고도 하는 이 기본 스레드는 모든 클릭 핸들러, 기타 UI, 수명 주기 콜백을 호출하는 스레드이기도 합니다. UI 스레드는 기본적인 스레드입니다. 앱이 명시적으로 스레드를 전환하거나 다른 스레드에서 실행되는 클래스를 사용하는 경우를 제외하고 앱이 하는 모든 작업은 기본 스레드에 있습니다.

이로 인해 어려움이 생길 수 있습니다. 즉, 뛰어난 사용자 환경을 보장하려면 UI 스레드가 원활하게 실행되어야 합니다. 앱이 눈에 띄는 일시중지 없이 사용자에게 표시되도록 하려면 기본 스레드가 16ms마다 또는 더 자주 화면을 업데이트하거나 초당 약 60프레임으로 화면을 업데이트해야 합니다. 이 속도에서 인간은 프레임 변경이 완벽히 원활하다고 인식합니다. 즉, 적은 시간에 많은 프레임을 렌더링해야 합니다. 따라서 Android에서는 UI 스레드 차단을 방지하는 것이 중요합니다. 이 컨텍스트에서 차단은 예를 들어 데이터베이스가 업데이트를 완료할 때까지 기다리는 동안 UI 스레드가 아무 작업도 하지 않는 것을 의미합니다.

이미지

인터넷에서 데이터 가져오기, 대용량 파일 읽기, 데이터베이스에 데이터 쓰기와 같은 많은 일반적인 작업은 16밀리초 이상 걸립니다. 따라서 코드를 호출하여 기본 스레드에서 이 같은 작업을 실행하면 앱이 일시중지되거나 끊기거나 멈출 수 있습니다. 그리고 기본 스레드를 너무 오랫동안 차단하면 앱이 비정상 종료될 수 있으며 '애플리케이션 응답 없음'(ANR) 대화상자가 표시될 수도 있습니다.

콜백

기본 스레드에서 작업을 완료하는 방법으로는 몇 가지 옵션이 있습니다.

기본 스레드를 차단하지 않고 장기 실행 작업을 이행하는 한 가지 패턴은 콜백입니다. 콜백을 사용함으로써 백그라운드 스레드에서 장기 실행 작업을 시작할 수 있습니다. 작업이 완료되면 인수로 제공되는 콜백이 호출되어 기본 스레드의 결과를 코드에 알립니다.

콜백은 훌륭한 패턴이지만 몇 가지 단점이 있습니다. 콜백을 매우 많이 사용하는 코드는 읽기 어렵고 추론하기가 더 어려워질 수 있습니다. 코드는 순차적으로 보이지만 콜백 코드는 나중에 비동기 시간에 실행되기 때문입니다. 또한 콜백은 예외와 같은 일부 언어 기능의 사용을 허용하지 않습니다.

코루틴

Kotlin에서 코루틴은 장기 실행 작업을 원활하고 효율적으로 처리하기 위한 솔루션입니다. Kotlin 코루틴을 사용하면 콜백 기반 코드를 순차 코드로 변환할 수 있습니다. 순차적으로 작성된 코드는 일반적으로 읽기가 더 쉬우며 예외와 같은 언어 기능을 사용할 수도 있습니다. 결국 코루틴과 콜백은 정확히 동일한 작업을 합니다. 즉, 장기 실행 작업에서 결과를 사용할 수 있을 때까지 기다렸다가 실행을 계속합니다.