JAVA

Java 8의 parallelStream 을 사용할때 Log4j 의 MDC 문제 해결하기

.노을. 2017. 3. 13. 14:52
반응형


log4j 의 MDC 에 대한 설명을 보면, 위의 그림처럼 thread safe 한 것으로 되어 있다. 하지만, java 의 forkJoin 을 사용하게 될 경우, thread safe 가 보장되지 않는다. 

java 8 의 parallelStream 을 사용할 경우, 내부적으로 forkJoin 을 통한 처리를 하고 있어, 동일한 현상이 발생한다. 

이 현상을 방지 하기 위해서는 아래와 같이 MDC 의 현재 contextMap 을 복사하고, 그 값을 사용하도록 셋팅하는 클래스 하나가 필요 하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import org.slf4j.MDC; 
import java.util.Map; 
 
public class MdcSnapshot {     
    private final Map<StringString> mdc;     
 
    private MdcSnapshot() {         
        this.mdc = MDC.getCopyOfContextMap();     
    }     
 
    public static MdcSnapshot getCurrentMdc() {         
        return new MdcSnapshot();     
    }     
 
    public void populateMdc() {         
        MDC.clear();         
        if (mdc != null) {             
            MDC.setContextMap(mdc);         
        }     
    } 
}
cs

만들어진 클래스의 사용법은 아래와 같다.

1
2
3
4
5
6
7
private void doThingsReallyFast(List<Thing> things) {     
    MdcSnapshot context = MdcSnapshot.getCurrentMdc();     
    things.parallelStream().forEach((thing) -> {         
        context.populateMdc();         
        doTheThing(thing);     
    }); 
}
cs


반응형