ThreadLocal 동시성 이슈 (ArrayList, HashMap, HashSet)
1965
작성자 없음
작성한 질문수 0
안녕하세요! 김영한님!!
수업 너무 유익하게 잘 듣고있습니다~!!
동시성 이슈를 막기 위해 ThreadLocal을 사용하는 부분 중에서 궁금한 점이 생겨서 질문 드립니다.
String, TraceId의 타입에 대해서는 ThreadLocal을 사용해서 동시성 이슈를 해결하였는데, 필드로 ArrayList, HashMap, HashSet을 사용하고 싶은 경우에는 동시성 이슈를 어떻게 해결하면 될까요 ?
구글링을 했었을 때에는 멀티쓰레드 환경에서는 HashMap 대신에 ConcurrentHashMap을 사용해라고 봤었고, ArrayList 대신에 CopyOnWirteArrayList를 사용해라고 봤었고, HashSet에 대해서는 제대로 찾지 못했습니다.
멀티쓰레드 환경에서 Thread-Safe하게 ArrayList, HashMap, HashSet을 사용하려면 어떻게 해야하나요 ?
답변 1
31
안녕하세요. 박재성님
동기화 된 컬렉션을 만드는 방법은 다음을 참고해주세요.
https://cornswrold.tistory.com/209
먼저 말씀드리면 강의 예제에서 설명드린 동시성 문제와 ConcurrentHashMap, 동기화 된 컬렉션등의 동시성 문제는 다른 문제입니다.
ConcurrentHashMap이나, 동기화 된 컬렉션은 데이터를 입력할 때와 조회할 때만 동시성이 보장됩니다.
예를 들어서
쓰레드 A: map.put("key", "abcdefg")
쓰레드 B: map.get("key")
이 경우 A의 map.put("key", "abcdefg")가 조금이라도 빠르다면 A가 먼저 실행되고, 그 다음에 B가 실행됩니다.
그런데 잘 생각해보시면, ConcurrentHashMap을 사용하더라도 이번 예제에서 발생하는 동시성 이슈를 막을 수는 없습니다. 왜냐하면 강의 예제에서 발생하는 동시성 문제는 단순히 put, get을 동시에 호출하는 문제가 아닙니다. put, get을 순서대로 호출해도 발생하는 더 넓은 범위의 동시성 문제입니다.
그렇다면 HashMap만 있으면 되지, ConcurrentHashMap은 왜 필요할까요?
map.put("key", "abcdefg")을 하는 동안 HashMap의 내부에서는 수 많은 일이 발생합니다. 예를 들어서 map의 노드를 생성하고 저장 위치를 찾고, 기존 데이터를 최적화 하는 등등 알고리즘을 위해 여러 객체를 생성하고 조정합니다. 이런 과정을 진행중인데 누군가 map.get("key")을 동시에 호출하게 되면 아직 알고리즘이 완성되지 않은 상태에서 get()을 호출하게 됩니다. 이 경우 메모리 누수나 엉뚱한 데이터가 조회되는 문제가 발생할 수 있습니다. put()이 아직 완성되지 않은 상태에서 get()을 호출하는 것이지요.
이런 경우 동기화 된 컬렉션이나 ConcurrentHashMap을 사용하게 되면 put()이 확실하게 다 끝난 상태에서 get()이 호출되는 것을 보장해줍니다.
추가로 이런 문제는 0.0001초의 순간에 put(), get()이 동시에 발생하는 경우에 나타나기 때문에 트래픽이 적은 서비스에서는 거의 문제가 되지 않습니다. 그래도 멀티쓰레드 상황에서 동시에 Map에 접근해야 한다면 ConcurrentHashMap을 사용해서 문제를 예방하는 것이 좋겠지요^^
감사합니다.
어드바이스 순서 디폴트 기준이 궁금합니다.
0
50
1
AspectV1 예제를 @Configuration 수동 등록으로도 가능한가요?
0
77
2
구체 클래스를 상속받아 확장한 형태도 클래스패턴/데코레이터 패턴이라고 칭하나요?
0
49
1
TraceTemplate 을 미리 빈으로 등록해서 사용할때 이렇게 설정하는게 맞는건가요?
0
53
1
Decorator 에서 추상메서드로 뺄때 질문 있습니다.
0
55
1
대상 클래스에 기본 생성자가 없을 때
0
74
1
스프링 부트 버전 4.0 aop 의존성 명칭 변경
1
340
2
final 키워드 사용 관련 질문
0
74
1
안녕하세요
0
63
1
ThradLocal 실무 사례
0
97
2
실무에서의 동시성 문제
0
62
1
로그 등 부가 기능에 대한 테스트코드
0
50
1
ProceedingJoinPoint와 MethodInvocation에 대하여
0
66
1
실무 멀티스레딩에 대한 궁금증
0
69
1
안녕하세요 질문있습니다
0
43
1
AspectV3 aop 실행 순서 문의 드립니다
0
37
1
MDC vs AOP 중에 고민중입니다.
0
74
1
순환참조
0
158
2
this를 단독으로 사용할때랑 파라미터 바인딩 할때 차이
0
77
1
빈 후처리에 등록 질문 있습니다.
0
73
1
AppConfig 설정하는 설명중에 이해가 안되는게 있습니다.
0
86
1
ThreadLocal을 지역변수로 선언하면 remove가 필요할까요?
0
115
2
@Aspect 어노테이션으로 생성된 Advisor의 Bean 저장 여부
0
66
1
ThreadLocal 사용시 부작용이 있을수 있을까요? (ThreadLocal.remove()를 잘한다고 해도..)
0
69
2





