목록Book/Kotlin 동시성 프로그래밍 (9)
시배's Android
연속체 전달 스타일 호출되는 함수에 연속체를 보내는 것을 전제로 하고 있어, 함수가 완료되는 대로 연속체를 호출할 것이다. 모든 일시 중단 연산은 연속체를 보내고 받고록 변환하는데 이러한 대부분의 복잡한 작업은 컴파일러가 수행한다. 일시 중단 연산은 상태 머신으로 변환되는데, 상태를 저장하고 복구하며 한 번에 코드의 한 부분을 실행한다. 연속체 public interface Continuation { public val context : CoroutineContext public fun resume(value : T) public fun resumeWithException(exception : Throwable) } CoroutineContext는 Continuation과 사용된다. resume() 함수..
동시성 코드 테스트 테스트를 할 때 단순히 테스트를 하는 것이 아니라 정확하게 해야 한다는 점이 매우 중요하다. 가정을 버려야 한다. 나무가 아닌 숲에 집중하라 테스트에 대한 추가 조언 버그 수정은 시나리오를 커버하는 테스트와 함께 수반돼야 한다. 동시성 버그가 애플리케이션의 다른 부분에 어떤한 방법으로 영향을 줄 것인지 항상 생각해야 한다. 동시성 작업을 위해 모든 값을 차례로 하는 테스트를 하지 말아야 한다. 구현을 하기 전에 복원력에 대해서 이야기하고, 항상 복원력을 위한 테스트를 해야 한다. 에지 케이스를 찾기 위해서 커버리지 보고서에서 분기 분석을 사용한다. 단위 테스트와 기능 테스트를 작성하는 시점에 대해 알아야 한다. 인터페이스를 사용해 종속성을 연결한다.
원자성 위반 이 유형의 오류는 정확한 동기화 없이 객체의 상태를 동시에 수정할 때 발생한다. 원자성 위반은 코틀린에서도 발생할 수 있지만 오류를 피할 수 있도록 디자인하는 데 도움이 되는 기본형을 제공한다. 원자성의 의미 연산이 단일하고 분할할 수 없을 때 이 연산을 원자적이라고 한다. 공유 상태에 관해 언급할 때 흔히 많은 스레드에서 하나의 변수를 읽거나 쓰는 것에 대해 이야기한다. 보통 원자적이지 않아서 문제가 발생한다. 공유 상태를 수정하는 코드 블록이 다른 스레드의 변경 시도와 겹치면서 이런 문제가 발생한다. 한 스레드가 현재 값을 바꾸는 중에 아직 쓰지는 않은 상태에서 다른 스레드가 현재 값을 읽을 수 있다. 코드 블록을 원자적으로 만들려면 블록 안에서 발생하는 어떤 메모리 액세스도 동시에 실행..
채널의 이해 채널은 동시성 코드 간에 서로 안전한 통신을 할 수 있도록 해주는 도구다. 채널은 실행 중인 스레드에 상관없이 서로 다른 코루틴 간에 메시지를 안전하게 보내고 받기 위한 파이프라인으로 생각할 수 있다. 채널 유형과 배압 Channel의 send()는 일시 중단 함수다. 흔히 배압이라고 하며 리시버가 실제로 처리할 수 있는 것보다 더 많은 요소들로 채널이 넘치지 않도록 도와준다. 배압을 구성하기 위해 채널에 대한 버퍼를 정의할 수 있다. 채널을 통해 데이터를 보내는 코루틴은 채널 안의 요소가 버퍼 크기에 도달하면 일시 중단된다. 채널에서 요소가 제거되는 즉시, 송신자는 다시 재개된다. 언버퍼드 채널 버퍼가 없는 채널을 언버퍼드 채널이라고 한다. RendezvousChannel send()를 호..
일시 중단 가능한 시퀀스 및 이터레이터 호출 사이에서 일시 중단되지만, 실행중에는 일시중단될 수 없다. 이로 인해 일시 중단 연산이 없어도 반복할 수 있다. 시퀀스와 이터레이터의 빌더는 CoroutineContext를 받지 않는다. 기본적으로 코드를 호출한 컨텍스트와 동일한 컨텐스트에서 코드가 실행됨을 의미한다. 정보 산출 후에만 일시 중지할 수 있다. 이를 위해서는 yield() 또는 yieldAll() 함수를 호출해야 한다. 이터레이터 인덱스로 요소를 검색할 수 없으므로 요소는 순서대로만 액세스할 수 있다. 더 많은 요소가 있는지 여부를 나타내는 hasNext() 함수가 있다. 요소는 한 방향으로만 검색할 수 있다. 이전 요소를 검색할 방법은 없다. 재설정 할 수 없으므로 한 번만 반복할 수 있다. ..
Repository With Suspend Functions 일시 중단 함수를 만들려면 시그니처에 suspend 제어자만 추가하면 된다. 코루틴 외부에서 이 함수를 호출하면 동작하지 않는다. interface ProfileServiceRepository { suspend fun fetchByName(name : String) : Profile suspend fun fetchById(id : Long) : Profile } class ProfileServiceClient : ProfileServiceRepository { override suspend fun fetchByName(name : String) : Profile { return Profile(1, name, 28) } override suspe..
비동기 함수 결과가 없는 비동기 함수 : 완료 여부를 모니터링할 수 있지만 결과를 갖지 않는 백그라운드 작업이 이런 유형에 속한다. 결과를 반환하는 비동기 함수 : 비동기 함수가 웹 서비스에서 정보를 가져올 때 거의 대부분 해당 함수를 사용해 정보를 반환하고자 할 것이다. 잡의 라이프 사이클 New : 존재하지만 아직 실행되지 않는 잡 잡은 기본적으로 launch()나 Job()을 사용해 생성될 때 자동으로 시작된다. 잡을 생성할 때 자동으로 시작되지 않게 하려면 CoroutineStart.LAZY를 사용해야 한다. Activie : 실행 중인 잡. 일시 중단된 잡도 활성으로 간주된다. start() : 잡이 완료될 때까지 기다리지 않고 잡을 시작한다. 일시 중단 함수나 코루틴에서 호출할 필요가 없다. ..
안드로이드의 UI 스레드 안드로이드는 뷰 계층을 생성하지 않은 스레드가 관련 뷰를 업데이트하려고 할 때마다 CalledFromWrongThreadException을 발생시킨다. 자바에서의 네트워크 동작은 기본적으로 블로킹된다. NetworkOnMainThreadException 발생 백그라운드에서 요청하고, UI 스레드에서 업데이트할 것 스레드 생성 CoroutineDispatcher 기본적으로 가용성, 부하, 설정을 기반으로 스레드 간에 코루틴을 분산하는 오케스트레이터다. asyn()는 Deferred를 반환하는데, 디퍼트 코루틴 프레임워크에서 제공하는 취소 불가능한 넌블로킹 퓨처를 의미한다. asyn() 블록 안에서 발생하는 예외는 그 결과에 첨부되는데, isCancelled와 getCancellat..