반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 안드로이드강좌
- kotlin강좌
- theming
- Compose
- 자바
- Coroutine
- 코틀린
- 스레드
- 회고
- 병럴프로그래밍
- 커스텀상태
- viewmodel
- 테스트
- Kotlin
- 안드로이드
- ReactiveProgramming
- 책
- 알게되는
- k8s
- 글또
- mockito
- android
- 코루틴
- g 단위테스트
- Gradle
- 안드로이드스튜디오
- 디자인패턴
- 병렬프로그래밍
- Rxjava
- 알고리즘
Archives
- Today
- Total
선생님, 개발을 잘하고 싶어요.
자바 병렬 프로그래밍 - 3부 10장 - 활동성을 최대로 높이기 본문
- 안전성(safety)과 활동성(liveness)의 상관 관계
- 활동성에 문제가 되는 상황을 알아보자.
- 문제가 되는 사항을 미연에 방지하는 방법을 알아보자.
데드락
- 식사하는 철학자 문제
- 원형 테이블에 둘러 앉은 철학자
- 자기 왼쪽에 있는 젓가락을 집은 다음, 오른쪽 젓가락을 사용할 수 있을 때까지 기다린 후, 오른쪽 젓가락을 집어서 식사를 한다고 하자.
- 모든 철학자가 자기가 확보한 왼쪽 젓가락을 놓지 않고 오른쪽 젓가락을 기다리다가 식사를 하지 못하게됨
- JVM은 데이터베이스 서버와 같이 데드락 상태를 추적하는 기능 ❌
- 데드락은 시스템에 부하가 걸리는 최악의 상황에서 모습을 드러낸다.
락 순서에 의한 데드락
- 두 개의 스레드가 서로 다른 순서로 동일한 락을 확보하려 할 때 발생
- 같은 순서로 락을 확보하도록 돼 있다면, 종속성 그래프에 사이클 ❌ 👉 데드락 ❌
- 🌟 모든 스레드에서 락을 모두 같은 순서로만 사용한다면 락 순서에 의한 데드락 ❌
동적인 락 순서에 의한 데드락
- 함수의 인자로 들어온 객체를 대상으로 락을 건다면?
fun transferMoney(from: Account, to: Account) {
synchronized(from) {
synchronized(to) {
// 함수 인자를 통해서 락 순서가 동적으로 변경
}
}
}
// 다음의 경우, 락 순서 싸이클이 생기고 데드락 발생 가능성
transferMoney(a, b)
transferMoney(b, a)
- Systen.identityHashCode 등의 메서드를 활용해 락 순서를 고정할 필요가 있다.
- 🌟 인자로 들어오는 객체, 혹은 동기화 객체 순서를 정렬해서 균일한 락 순서를 가지도록 해야한다.
객체 간의 데드락
class Taxi {
val dispatcher: Dispatcher
@Synchronized
fun getLocation(): Point
@Synchronized // 1. Taxi 객체의 락을 확보
fun setLocation(...) {
dispatcher.notifyAvailable() // 2. Dispatcher 객체의 락을 확보
}
}
class Dispatcher {
@Synchronized // 1. Dispatcher 객체의 락을 확보
fun notifyAvailable() {
taxi.getLocation() // 2. Taxi 객체의 락을 확보
}
}
// 서로 다른 순서로 락을 가져가려는 상황 발생
- 락을 확보하고 에일리언 매소드를 호출하는지 체크하기
- 👀 에일리언 메소드 👉 정의는 되어있지만 기능이 만들어져 있지 않은 메소드, 내부에서 어떤 동작이 일어날 지 모르는 메소드
오픈 호출
- 오픈 호출(open call) 👉 락을 전혀 확보하지 않은 상태에서 메소드를 호출하는 것
- 오픈 호출을 활용하면, 활동성 분석도 간편
- synchronized 블록도 범위를 최대한 줄이기
- 🌟 프로그램 작성할 때 최대한 오픈 호출한다. 데드락 분석이 쉬워진다.
리소스 데드락
- 필요한 자원을 사용하기 위해 대기하는 과정도 데드락 ⭕️
- 스레드 부족 데드락, 다른 작업 실행 결과를 사용해야 하는 작업이 있다면, 스레드 소모성 데드락 원인 되기 쉽다.
데드락 방지 및 원인 추적
- 가능하다면 한 번에 하나의 락만 사용하게 개발
- 락 사용 순서를 설계 단계부터 고려
- 데드락 발생 가능성 여부 판단
- 여러 개의 락 확보하는 부분 파악
- 락을 지정된 순서에 맞춰 사용하도록 한다
- 👉 오픈 호출 방법을 사용하면 이같은 분석 작업이 쉬워진다.
락의 시간 제한
- Lock 클래스 등 명시적 락은 일정 시간 동안 락 확보 못하면 tryLock에서 오류 발생시킬 수 있다.
- 에러를 받고 재시도하도록 할 수 도 있겠다.
스레드 덤프를 활용한 데드락 분석
그 밖의 활동성 문제점
- 소모, 놓친 신호, 라이브락
소모(starvation)
- 소모 👉 스레드가 작업 진행하는 데 꼭 필요한 자원을 영영 할당받지 못하는 경우
- 자바에서 소모 상황이 발생하는 대부분의 원인
- 스레드 우선 순위를 적절치 못하게 올리거나 내리는 부분
- 🌟 스레드 우선 순위는 왠만하면 건드리지 말자. 활동성 문제를 일으킬 수 있고, 플랫폼 종속적이 되곤 한다.
- 락을 확보한 채 종료되지 않는 코드 실행 시 👉 다른 스레드는 해당 락을 영영 가저갈 수 없어 소모 상황 발생
- 스레드 우선 순위를 적절치 못하게 올리거나 내리는 부분
형편 없는 응답성
- 응답성이 떨어지는 상황
라이브락(livelock)
- 라이브락 👉 실패할 수밖에 없는 기능을 계속해서 재시도하는 경우
- e.g. 메시지 전송에 실패했을 때, 해당 트랜젝션을 롤백하고 큐의 맨 뒤에 쌓아두는 애플리케이션에서 발생
- 회복 불가능한 오류를 회복 가능하다고 판단해 계속 재시도하는 과정에서 나타나는 문제
- 각 스레드가 다른 스레드 응답에 따라 각자의 상태를 계속 변경하느라 실제 작업은 전혀 못하는 경우에도 발생
- 임의의 시간 동안 기다리다가 재시도 하는 방법 등으로 해결
요약
- 락 순서에 의한 데드락이 가장 흔한 활동성 문제
- 프로그램을 개발할 때 오픈 호출 방법을 사용할 것을 고민해보자.
'일상 > 책 리뷰' 카테고리의 다른 글
단위 테스트: 생산성과 품질을 위한 단위 테스트 원칙과 패턴 - 1부 더 큰 그림 (0) | 2022.07.18 |
---|---|
자바 병렬 프로그래밍 - 3부 11장 - 성능, 확장성 (0) | 2022.07.03 |
자바 병렬 프로그래밍 - 2부 9장 - GUI 애플리케이션 (0) | 2022.06.25 |
자바 병렬 프로그래밍 - 2부 8장 - 스레드 풀 활용 (0) | 2022.06.23 |
자바 병렬 프로그래밍 - 2부 7장 - 중단 및 종료 (0) | 2022.06.19 |
Comments