Notice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 안드로이드 라이선스 종류
- rxjava disposable
- Rxjava Observable
- rxjava hot observable
- 객체
- 안드로이드 유닛테스트란
- rxjava cold observable
- 안드로이드 라이선스
- 안드로이드 레트로핏 crud
- 플러터 설치 2022
- 멤버변수
- 2022 플러터 설치
- android retrofit login
- ar vr 차이
- jvm이란
- 서비스 쓰레드 차이
- android ar 개발
- 안드로이드 os 구조
- 큐 자바 코드
- 스택 큐 차이
- 안드로이드 유닛 테스트 예시
- 클래스
- 서비스 vs 쓰레드
- 2022 플러터 안드로이드 스튜디오
- 스택 자바 코드
- jvm 작동 원리
- 자바 다형성
- 안드로이드 유닛 테스트
- 안드로이드 레트로핏 사용법
- ANR이란
Archives
- Today
- Total
나만을 위한 블로그
[Android] 경쟁 상태(Race Condition)란? 본문
728x90
반응형
아래는 경쟁 상태를 설명하는 영문 위키백과다.
https://en.wikipedia.org/wiki/Race_condition
경쟁 조건은 시스템의 실질적인 동작이 제어할 수 없는 다른 이벤트의 순서, 타이밍에 의존해서 예기치 않거나 일관되지 않은 결과를 초래하는 시스템 상태를 말한다. 가능한 동작 중 하나 이상이 바람직하지 않은 경우 버그가 된다...(중략)...특히 논리 회로나 멀티 쓰레드, 분산 소프트웨어 프로그램에서 경쟁 조건이 발생할 수 있다. 상호 배제를 사용하면 분산 소프트웨어 시스템에서 경쟁 조건을 막을 수 있다...(중략)...동시 실행되는 코드 경로가 여러 개 있을 때 소프트웨어에서 경합 조건이 발생할 수 있다. 여러 코드 경로가 예상과 다른 시간이 걸리면 예상과 다른 순서로 완료되서 예기치 않은 동작으로 인해 버그가 발생할 수 있다. 심각한 경합 조건은 잘못된 실행, 소프트웨어 버그를 유발한다. 치명적 경쟁 조건은 프로세스나 쓰레드가 일부 공유상태에 의존할 때 발생한다. 공유 상태에 대한 작업은 상호배타적이어야 하는 중요한 섹션에서 수행된다...(중략)...경함 조건은 최종 결과가 비결정적이고 간섭하는 쓰레드 간의 상대적 타이밍에 따라 달라지기 때문에 재현, 디버깅이 어려울 수 있다. 따라서 이런 성격의 문제는 디버그 모드로 실행하거나 로그 추가, 디버거를 연결하면 사라질 수 있다. 디버깅 중에 이렇게 사라지는 버그를 하이젠버그라고 한다. 따라서 신중한 소프트웨어 설계를 통해 경쟁 조건을 피하는 게 좋다
경쟁 조건은 안드로이드에서도 발생할 수 있는 문제다. 어떤 메모리 위치를 대상으로 둘 이상의 읽기 or 쓰기 작업이 거의 동시 실행되어 어떤 작업이 먼저 완료될지 예측할 수 없는 경우에 발생할 수 있다. 안드로이드에선 아래 경우에 발생할 수 있다.
- 비동기 작업 : 쓰레드, 코루틴 등을 쓸 때 여러 쓰레드가 공유 리소스에 접근할 때
- UI 업데이트 : 백그라운드 쓰레드에서 UI를 직접 업데이트하려고 할 때
- 싱글톤 패턴 : 멀티 쓰레드 환경에서 싱글톤 인스턴스를 만들 때 적절한 동기화가 없는 경우
- 쉐어드 프리퍼런스 : 여러 쓰레드에서 동시에 읽기 / 쓰기 작업을 수행할 때
- DB : 동시에 여러 DB 트랜잭션이 실행될 때
- 네트워크 요청 : 여러 쓰레드에서 동시에 네트워크 요청을 처리할 때
- 서비스 시작 / 중지 : 서비스의 생명주기 함수가 동시 호출될 때
- 브로드캐스트 리시버 : 여러 리시버가 동시에 같은 리소스에 접근할 때
텍스트뷰가 있고 두 쓰레드에서 이 텍스트뷰에 각각 1, 2라는 숫자를 표시하라고 동시에 명령을 내린다면 텍스트뷰는 결국 어떤 숫자를 표시해야 하는가?
이런 경우가 발생하지 않게 조심해야 한다. 안드로이드에서 경쟁 조건이 발생하지 않게 하려면 아래 방법들을 고려해볼 수 있다.
방법 | 설명 |
동기화 매커니즘 사용 | synchronized를 메서드나 코드 블록에 써서 한 번에 하나의 쓰레드만 접근할 수 있게 하거나, Lock 인터페이스를 써서 동기화를 세밀하게 제어한다 |
thread-safe한 자료구조 활용 | ConcurrentHashMap 등 동시성을 지원하는 컬렉션을 사용하거나, AtomicBoolean 등 atomic 타입을 써서 원자적 연산을 수행한다 |
핸들러 사용 | 메인 쓰레드(UI 쓰레드)와 백그라운드 쓰레드 간 통신을 안전하게 처리한다 |
쓰레드 풀 사용 | ExecutorService를 써서 동시성을 제어한다 |
불변 객체 사용 | 원천적으로 동시성 문제를 방지할 수 있는 방법이다 |
volatile 키워드 사용 | 변수의 가시성을 보장해서 멀티 쓰레드 환경에서의 일관성을 유지한다 |
SingleThreadExecutor 사용 | 순차적 실행이 필요한 작업에 사용한다 |
코루틴 활용 | 비동기 프로그래밍을 단순화하고 동시성 관리를 개선한다 |
ConcurrentHashMap은 코틀린 공식문서에만 있을 줄 알았는데 의외로 안드로이드 디벨로퍼에도 공식문서가 존재한다.
https://developer.android.com/reference/kotlin/java/util/concurrent/ConcurrentHashMap
Atomic이 붙은 타입은 멀티 쓰레드 환경의 중요 개념인 동시성, 가시성, 원자성 중 원자성을 보장하기 위해 설계된 타입이다. 하나의 변수에 원자적 연산이 필요하거나 원자적 접근을 보장할 때 사용할 수 있다.
원자적 연산은 읽기, 쓰기, 갱신 등 작업이 중단 없이 완전하게 실행되는 걸 말한다. 원자성을 더 알아보는 건 이 포스팅의 범위를 넘기 때문에 생략한다.
반응형
'Android' 카테고리의 다른 글
[Android] 초기 데이터 로드 2 : 의문점 해소하기 (0) | 2024.10.13 |
---|---|
[Android] 단위 테스트 시 Stub, Mock, Fake, Spy 선택 기준 (0) | 2024.10.11 |
[Android] 초기 데이터 로드 : LaunchedEffect vs ViewModel (0) | 2024.09.23 |
[Android] BuildConfig를 찾을 수 없는 경우 해결법 (0) | 2024.09.16 |
[Android] 뷰모델에서 데이터 불러오기 Best Practice (0) | 2024.09.15 |
Comments