인프런 커뮤니티 질문&답변
작성자 없음
작성자 정보가 삭제된 글입니다.
ConcurrentHashMap 사용 질문
작성
·
1.1K
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();
}
}




