시배's Android

Kotlin Coroutines Deep Dive | 14장. 공유 상태로 인한 문제 본문

Book/Kotlin Coroutines Deep Dive

Kotlin Coroutines Deep Dive | 14장. 공유 상태로 인한 문제

si8ae 2024. 2. 12. 15:44

동기화 블로킹

  • 자바에서 사용되는 전통적인 도구인 synchronized 블록이나 동기화된 컬렉션을 사용해 해결할 수 있습니다.
  • 가장 큰 문제점은 synchronized 블록 내부에서 중단 함수를 사용할 수 없다는 것입니다.
  • synchronized 블록에서 코루틴이 자기 차례를 기다릴 때 스레드를 블로킹한다는 것입니다.

원자성

  • 자바는 다양한 원자값을 가지고 있습니다.
  • 원자값을 활용한 연산은 빠르며 스레드 안전을 보장합니다.
  • 원자성은 하나의 primitive 변수 또는 하나의 reference의 안전을 보장하기 위해 사용되지만, 좀 더 복잡한 경우에는 다른 방법을 사용해야 합니다.

싱글스레드로 제한된 디스패처

  • 싱글스레드 디스패처를 사용하는 것이 공유 상태와 관련된 대부분의 문제를 해결하는 가장 쉬운 방법입니다.
  • coarse-grained 스레드 한정이 있습니다.
  • 이 방법은 디스패처를 싱글스레드로 제한한 withContext로 전체 함수를 래핑하는 방법입니다.
  • fine-grained 스레드 한정이 있습니다.
  • 이 방법은 디스패처를 상태를 변경하는 구문들만 래핑합니다.

뮤텍스

  • 첫 번째 코루틴이 lock을 호출하면 열쇠를 가지고 중단 없이 작업을 수행합니다.
  • 또 다른 코루틴이 lock을 호출하면 첫 번째 코루틴이 unlock을 호출할 때까지 중단됩니다.
  • 또 다른 코루틴이 lock 함수를 호출하면, 마찬가지로 작업을 중단한 뒤에 두 번째 코루틴 다음 순서로 큐에 들어가게 됩니다.
  • 첫 번째 코루틴이 unlock 함수를 호출하면 열쇠를 반납하고 두 번째 코루틴이 재개한 뒤 lock 함수를 통과하게 됩니다.
  • lock으로 시작해 finally 블록에서 unlock을 호출하는 withLock 함수를 사용하여 블록 내에서 어떤 예외가 발생하더라도 자물쇠를 성공적으로 풀 수 있게 할 수 있습니다.
  • synchronized 블록과 달리 뮤텍스가 가지는 중요한 이점은 스레드를 블로킹하는 대신 코루틴을 중단시킨다는 것입니다.
  • 뮤텍스의 문제점 중 첫 번째는 뮤텍스를 사용할 때 맞닥뜨리는 위험한 경우는 코루틴이 락을 두 번 통과할 수 없다는 것입니다.
  • 뮤텍스의 문제점 중 두 번째는 코루틴이 중단되었을 때 뮤텍스를 풀 수 없다는 점입니다.

세마포어 

  • Semaphore는 여러 개의 접근을 허용하므로, acquire, release, withPermit 함수를 가지고 있습니다.
  • 세마포어는 공유 상태로 인해 생기는 문제를 해결할 수는 없지만, 동시 요청을 처리하는 수를 제한할 때 사용할 수 있어 처리율 제한 장치를 구현할 때 도움이 됩니다.