Скажем, у меня есть List<Integer> ints = new ArrayList<>();
и я хочу добавить к нему значения и сравнить результаты параллельного выполнения с использованием forEach()
и Collectors.toList()
.
Сначала я добавляю в этот список некоторые значения из последовательного IntStream и forEach:
IntStream.range(0,10).boxed().forEach(ints::add);
И я получаю правильный результат:
ints ==> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Теперь я .clear()
список и сделать то же самое параллельно:
IntStream.range(0,10).parallel().boxed().forEach(ints::add);
Теперь из-за многопоточности я получаю неверный результат:
ints ==> [6, 5, 8, 9, 7, 2, 4, 3, 1, 0]
Теперь я переключаюсь на сбор одного и того же потока целых чисел:
IntStream.range(0,10).parallel().boxed().collect(Collectors.toList());
И я получаю правильный результат:
ints ==> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Вопрос: Почему два параллельных исполнения дают разные результаты и почему Collector
производит правильный результат?
Если forEach
производит случайный результат, Collector
тоже должен. Я не указывал какую-либо сортировку, и я думаю, что внутренне он добавляет в список, как я сделал вручную, используя forEach
. Поскольку он делает это параллельно, он add
метод, чтобы получить значения в неуказанном порядке. Тестирование сделано в JShell.
EDIT: Нет дубликатов здесь. Я понимаю связанный вопрос. Почему Коллектор дает правильный результат? Если бы он произвел другой случайный результат, я бы не спросил.