digital-garden/notes/Собеседования/Задачи/Задача 24.md
2024-06-13 21:01:37 +03:00

3.5 KiB
Raw Permalink Blame History

Да, конечно. Вот простой пример, где Mapped Diagnostic Context (MDC) от Spring не будет работать с параллельным стримом:

import org.slf4j.MDC;
import java.util.stream.IntStream;

public class ParallelStreamWithMDC {

    public static void main(String[] args) {
        MDC.put("testKey", "testValue");

        IntStream.range(0, 10).parallel().forEach(i -> {
            System.out.println("Value: " + i + ", MDC Value: " + MDC.get("testKey"));
        });
        
        MDC.clear();
    }
}

В этом примере мы добавляем значение в MDC и затем пытаемся получить его внутри параллельного стрима. Однако, поскольку каждое значение в стриме обрабатывается в отдельном потоке, и MDC не передает данные между потоками автоматически, мы не получим ожидаемое значение из MDC.

Обратите внимание, что это является проблемой не только для Spring, но и для любой другой библиотеки, которая использует MDC, поскольку это ограничение MDC, а не Spring. Если вам нужно передавать данные MDC между потоками, вы должны сделать это вручную.

Понимаю, вы ищете пример, который будет несколько сложнее для понимания. Вот один из таких примеров:

import org.slf4j.MDC;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class ParallelStreamWithMDC {

    public static void main(String[] args) {
        List<Runnable> tasks = IntStream.range(0, 10)
            .boxed()
            .map(i -> {
                String mdcValue = "testValue" + i;
                return (Runnable) () -> {
                    MDC.put("testKey", mdcValue);
                    System.out.println("Value: " + i + ", MDC Value: " + MDC.get("testKey"));
                    MDC.clear();
                };
            })
            .collect(Collectors.toList());

        tasks.parallelStream().forEach(Runnable::run);
    }
}

В этом примере мы создаем список задач, каждая из которых устанавливает свое значение в MDC, выводит его, а затем очищает MDC. Затем мы запускаем эти задачи в параллельном стриме.

Проблема заключается в том, что MDC не является потокобезопасным и не передается автоматически между потоками. Поэтому, когда мы пытаемся получить значение из MDC внутри задачи, мы можем получить непредсказуемые результаты, потому что другие потоки могут одновременно изменять MDC.

Это может быть сложно заметить на первый взгляд, особенно если вы не знакомы с тем, как работает MDC, и это хороший пример того, как небольшая деталь может привести к большим проблемам в многопоточной среде.