mystic-agit 개발 블로그

ConcurrentHashMap 을 통한 ConcurrentModificationException 해소 본문

Kotlin

ConcurrentHashMap 을 통한 ConcurrentModificationException 해소

mystic-agit 2023. 3. 14. 18:36

java.util.ConcurrentModificationException

 

MutablaMap 으로 선언한 지역 변수에서 순회(for-each) 진행 중 발생하였다.

순회 과정에서 index를 remove 시키진 않지만 값이 업데이트가 될 수 있는 경우였다.

 

// ...(생략)...
private val cachedMap: MutableMap<String, MyStucture>

init {
    cachedMap = androidx.collection.ArrayMap()
}

fun addData(dataList: List<MyStucture>) {
    for (data in dataList) {
        cachedMap[data.id] = data
    }
}
// ...(생략)...

 

addData 메서드가 호출될 수 있는 경우는 비동기적으로 여러곳에서 호출될 수 있는 구조였고,
이로인해 ConcurrentModificationException 에러가 발생한 것으로 보인다.

 

동시접근을 배제하기 위해 Iterator를 사용하여 데이터를 업데이트 하거나 메서드 자체를 @Synchronized 메서드로 처리할 수도 있지만 MutableMap 대신 ConcurrentHashMap 을 사용하여 대응할 수 있었다.

(현재 시스템에서 로직 코드 변경을 최소화할 수 있는 방법이라 생각되었다.)

 

// ...(생략)...
private val cachedMap by lazy { ConcurrentHashMap<String, MyStucture>)_ }

fun addData(dataList: List<MyStucture>) {
    for (data in dataList) {
        cachedMap[data.id] = data
    }
}
// ...(생략)...

 

ConcurrentHashMap 클래스 내에는 DEFAULT_CAPACITY 값을 두고 동시 접근 시 커버할 수 있는 버킷을 컨트롤한다.
DEFAULT_CAPACITY는 16으로 되어있으나 MAXIMUM_CAPACITY = 1 << 30 으로 안내하고 있어 범위 내에서 CAPACITY를 조정할 수 있다.

 

동시접근이 적당수준(?) 허락되는 경우라면 ConcurrentHashMap을 통해 성능 저하없이 커버가 가능할 것으로 보인다.

 

 

참고 레퍼런스

 

[Java] ConcurrentHashMap 이란 무엇일까?

들어가기 전에 HashTable, HashMap, ConcurrnetHashMap은 많이 유사한 특징들을 가지고 있습니다. 하지만 세부적으로 보면 조금씩 꽤나 차이가 있는데요. 간단하게 어떤 차이가 있는지 알아보면서 시작하

devlog-wjdrbs96.tistory.com

 

Comments