Я пытаюсь определить, насколько потокобезопасен MDC
при использовании Cacheable ThreadPools или аннотации Spring Async.
У меня есть метод, который вызывает несколько CompletableFuture<>
и выполняет их с использованием пулов потоков.
@Async
public CompletableFuture<List> someMethod(String request) {
try {
MDC.put("request", request)
MDC.put("loggable1", "loggable1");
MDC.put("loggable2", "loggable2");
log.info("Log Event");
} finally {
MDC.clear();
}
}
Соответствующие части из MDCAdapter от Logback
final ThreadLocal<Map<String, String>> copyOnThreadLocal = new ThreadLocal<Map<String, String>>();
public void put(String key, String val) throws IllegalArgumentException {
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
}
Map<String, String> oldMap = copyOnThreadLocal.get();
Integer lastOp = getAndSetLastOperation(WRITE_OPERATION);
if (wasLastOpReadOrNull(lastOp) || oldMap == null) {
Map<String, String> newMap = duplicateAndInsertNewMap(oldMap);
newMap.put(key, val);
} else {
oldMap.put(key, val);
}
}
public void clear() {
lastOperation.set(WRITE_OPERATION);
copyOnThreadLocal.remove();
}
public void remove(String key) {
if (key == null) {
return;
}
Map<String, String> oldMap = copyOnThreadLocal.get();
if (oldMap == null)
return;
Integer lastOp = getAndSetLastOperation(WRITE_OPERATION);
if (wasLastOpReadOrNull(lastOp)) {
Map<String, String> newMap = duplicateAndInsertNewMap(oldMap);
newMap.remove(key);
} else {
oldMap.remove(key);
}
}
Поскольку ThreadPools повторно используют уже созданные потоки, а MDC использует карту контекста ThreadLocal. Возможно ли, что мы можем либо потерять, либо испортить значения, хранящиеся в MDC? Если да, то каковы потенциальные сценарии, в которых это может произойти?