ConcurrentHashMap 사용 질문
1142
작성자 없음
작성한 질문수 0
https://www.inflearn.com/questions/347336
해당 질문 글에서 ConcurrentHashMap 을 사용하더라도 예제에 발생하는 동시성 이슈를 막을 수 없다고 하셔서
저도 궁금해서 ConcurrentHashMap 을 사용한 LogTrace를 만들어서 테스트를 몇 번 돌려봤는데
정상적으로 처리되는거 같은데 또 다른 이슈가 있는건가요??
package hello.advanced.trace.logtrace;
import java.util.concurrent.ConcurrentHashMap;
import hello.advanced.trace.TraceId;
import hello.advanced.trace.TraceStatus;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class MapLogTrace implements LogTrace {
private static final String START_PREFIX = "-->";
private static final String COMPLETE_PREFIX = "<--";
private static final String EX_PREFIX = "<X-";
private ConcurrentHashMap<Thread, TraceId> map = new ConcurrentHashMap<>();
@Override
public TraceStatus begin(String message) {
syncTraceId();
Long startTimeMs = getCurrentTimeMillis();
TraceId traceId = map.get(Thread.currentThread());
log.info("[{}] {}{}", traceId.getId(), addSpace(START_PREFIX, traceId.getLevel()), message);
return new TraceStatus(traceId, startTimeMs, message);
}
private void syncTraceId() {
Thread thread = Thread.currentThread();
TraceId traceId = map.get(thread);
if (traceId == null) {
map.put(thread, new TraceId());
} else {
map.put(thread, traceId.createNextId());
}
}
@Override
public void end(TraceStatus status) {
complete(status, null);
}
@Override
public void exception(TraceStatus status, Exception ex) {
complete(status, ex);
}
private void complete(TraceStatus status, Exception ex) {
Long stopTimeMs = getCurrentTimeMillis();
long resultTimeMs = stopTimeMs - status.getStartTimeMs();
TraceId traceId = status.getTraceId();
if (ex == null) {
log.info("[{}] {}{} time={}ms", traceId.getId(), addSpace(COMPLETE_PREFIX, traceId.getLevel()),
status.getMessage(), resultTimeMs);
} else {
log.info("[{}] {}{} time={}ms ex={}", traceId.getId(), addSpace(EX_PREFIX, traceId.getLevel()),
status.getMessage(), resultTimeMs, ex.toString());
}
releaseTraceId();
}
private void releaseTraceId() {
Thread thread = Thread.currentThread();
TraceId traceId = map.get(thread);
if (traceId.isFirstLevel()) {
map.remove(thread);
} else {
map.put(thread, traceId.createPreviousId());
}
}
private String addSpace(String prefix, int level) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < level; i++) {
sb.append((i == level - 1) ? "|" + prefix : "| ");
}
return sb.toString();
}
private Long getCurrentTimeMillis() {
return System.currentTimeMillis();
}
}
답변 1
SpringBoot 4.0.6 버전에서 PackageLogTracePostProcessor exception
0
85
3
어드바이스 순서 디폴트 기준이 궁금합니다.
0
75
1
AspectV1 예제를 @Configuration 수동 등록으로도 가능한가요?
0
102
2
구체 클래스를 상속받아 확장한 형태도 클래스패턴/데코레이터 패턴이라고 칭하나요?
0
73
1
TraceTemplate 을 미리 빈으로 등록해서 사용할때 이렇게 설정하는게 맞는건가요?
0
69
1
Decorator 에서 추상메서드로 뺄때 질문 있습니다.
0
63
1
대상 클래스에 기본 생성자가 없을 때
0
83
1
스프링 부트 버전 4.0 aop 의존성 명칭 변경
1
407
2
final 키워드 사용 관련 질문
0
85
1
안녕하세요
0
75
1
ThradLocal 실무 사례
0
106
2
실무에서의 동시성 문제
0
73
1
로그 등 부가 기능에 대한 테스트코드
0
60
1
ProceedingJoinPoint와 MethodInvocation에 대하여
0
77
1
실무 멀티스레딩에 대한 궁금증
0
82
1
안녕하세요 질문있습니다
0
49
1
AspectV3 aop 실행 순서 문의 드립니다
0
46
1
MDC vs AOP 중에 고민중입니다.
0
85
1
순환참조
0
168
2
this를 단독으로 사용할때랑 파라미터 바인딩 할때 차이
0
83
1
빈 후처리에 등록 질문 있습니다.
0
85
1
AppConfig 설정하는 설명중에 이해가 안되는게 있습니다.
0
98
1
ThreadLocal을 지역변수로 선언하면 remove가 필요할까요?
0
122
2
@Aspect 어노테이션으로 생성된 Advisor의 Bean 저장 여부
0
76
1





