57 lines
3.5 KiB
Markdown
57 lines
3.5 KiB
Markdown
|
Да, конечно. Вот простой пример, где Mapped Diagnostic Context (MDC) от Spring не будет работать с параллельным стримом:
|
|||
|
|
|||
|
```java
|
|||
|
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 между потоками, вы должны сделать это вручную.
|
|||
|
|
|||
|
Понимаю, вы ищете пример, который будет несколько сложнее для понимания. Вот один из таких примеров:
|
|||
|
|
|||
|
```java
|
|||
|
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, и это хороший пример того, как небольшая деталь может привести к большим проблемам в многопоточной среде.
|