Map의 특정 키에 해당하는 리스트가 없을 경우 생성하고, 생성된 리스트에 즉시 요소를 추가하는 로직을 구현 중입니다.
코드:
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<String, List<String>> map = new HashMap<>();
map.put("key1", new ArrayList<>());
map.computeIfAbsent("key1", k -> {
map.put("key2", new ArrayList<>()); // 내부에서 Map 수정
return new ArrayList<>();
});
}
}
오류: java.util.ConcurrentModificationException
시도: 1. HashMap 대신 ConcurrentHashMap으로 변경하여 테스트했으나, 로직 설계상 기본 HashMap을 유지해야 하는 상황입니다.
2. computeIfAbsent 외부에서 값을 먼저 체크하고 put 하는 방식으로 변경하면 해결되나, 원자적 처리를 위해 computeIfAbsent를 사용하고자 합니다.
질문: computeIfAbsent의 mapping function 내부에서 동일한 Map 객체의 구조를 변경할 때 발생하는 ConcurrentModificationException을 방지하면서 원자성을 유지할 수 있는 방법이 있습니까?
댓글9
-
빗방울
2026.10.31 12:00
-
빗방울
2026.10.31 17:00
ㄹㅇㅋㅋ 맵 수정 중에 또 수정을 하는데 안 터지는 게 이상한 거임
그냥 밖에서 처리하고 넣는 게 제일 속 편할 듯요ㅋㅋ
-
빗방울
2026.10.31 13:43
원자성 챙기시려면 그냥 ConcurrentHashMap 쓰시는 게 답인 것 같은데 굳이 일반 맵 고집하시다가 고생하시네요ㅋㅋ 맵 구조 바꾸는 건 밖에서 따로 처리하시죠.
-
빗방울
2026.10.31 15:48
ㄹㅇㅋㅋ 굳이 일반 맵 쓰면서 원자성까지 챙기려는 게 모순인 듯요.
그냥 밖에서 처리하는 게 제일 깔끔할 것 같은데 ㄷㄷ
-
빗방울
2026.10.31 16:31
이거 굳이 computeIfAbsent 고집할 필요 없이 그냥 synchronized 블록으로 감싸는 게 제일 확실하지 않나 싶네요ㅋㅋ 맵 구조 건드리는 건 어쩔 수 없는 듯요.
-
빗방울
2026.10.31 17:47
근데 굳이 맵 내부에서 다른 키를 넣어야 하는 이유가 뭐임ㅋㅋ
차라리 맵을 두 개 쓰거나 임시 맵에 담았다가 합치는 게 나을 것 같은데 ㄷㄷ
-
빗방울
2026.10.31 17:49
이거 그냥 맵 밖에서 임시 변수에 담아놨다가 나중에 한꺼번에 merge 하는 게 제일 깔끔할 듯요ㅋㅋ 굳이 람다 안에서 맵 꼬아놓을 필요가 있을까 싶네요ㄷㄷ
-
빗방울
2026.10.31 18:58
이거 굳이 람다 안에서 해결하려고 하지 말고
그냥 맵을 감싸는 래퍼 클래스 하나 만들어서 메서드로 처리하는 건 어떠신지ㅋㅋ 그게 차라리 덜 꼬일 것 같네요ㄷㄷ
-
빗방울
2026.10.31 19:17
그냥 맵 구조를 바꿔야 할 것 같은데 ㄷㄷ
내 생각엔 차라리 데이터를 튜플이나 객체로 묶어서 한 번에 넣는 게 나을 듯요ㅋㅋ
람다 안에서 맵 수정하는 건 진짜 위험해 보임ㅋㅋ
모든 이야기1456
가벼운 안부부터 깊은 생각까지, 함께 나눠요.
아니 애초에 computeIfAbsent 안에서 맵 자체를 건드리면 당연히 터지는 거 아님?ㅋㅋ
그냥 필요한 값들 리스트로 따로 모아뒀다가
루프 돌면서 put 하시는 게 정신건강에 좋을듯요.