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, и это хороший пример того, как небольшая деталь может привести к большим проблемам в многопоточной среде. |