при параллельном вычислении для некоторых конвейеров, содержащих промежуточные операции с состоянием, может потребоваться несколько проходов данных или может потребоваться буферизация значимых данных
ал о безгражданстве и наткнулся на это вдоктор:
Результаты потокового конвейера могут быть недетерминированными или неправильными, если поведенческие параметры для операций потока являются состоящими. Лямбда с состоянием (или другой объект, реализующий соответствующий функциональный интерфейс) - это тот, чей результат зависит от любого состояния, которое может измениться во время выполнения потокового конвейера.
Теперь, если у меня есть список строк (strList
скажем), а затем пытается удалить дубликаты строк с помощью параллельных потоков следующим образом:
List<String> resultOne = strList.parallelStream().distinct().collect(Collectors.toList());
или если мы хотим, чтобы регистр не учитывался:
List<String> result2 = strList.parallelStream().map(String::toLowerCase)
.distinct().collect(Collectors.toList());
Может ли этот код иметь какие-либо проблемы, так как параллельные потоки будут разделять входные данные и различать их в одном фрагменте, что не обязательно означает различное во всем входном сигнале?
РЕДАКТИРОВАТЬ (Краткое резюме ответов ниже)distinct
является операцией с состоянием, и в случае промежуточных операций с состоянием параллельные потоки могут потребовать многократных проходов или существенных издержек буферизации. Такжеdistinct
может быть реализовано более эффективно, если порядок элементов не имеет значения. Также согласнодоктор:
Для упорядоченных потоков выбор отдельных элементов является стабильным (для дублированных элементов элемент, появляющийся первым в порядке встречи, сохраняется.) Для неупорядоченных потоков гарантии стабильности не предоставляются.
Но в случае, когда упорядоченный поток, работающий в параллельном разряде, может быть нестабильным - это означает, что он будет содержать произвольный элемент в случае дубликатов и не обязательно первый, как ожидаетсяdistinct
в противном случае.
Изссылка:
Внутренне, операция Different () сохраняет Set, который содержит элементы, которые были замечены ранее, но он скрыт внутри операции, и мы не можем получить его из кода приложения.
Таким образом, в случае параллельных потоков он, вероятно, будет использовать весь поток или может использовать CHM (например,ConcurrentHashMap.newKeySet()
). И для заказанных, скорее всего, будет использоватьLinkedHashSet
или аналогичный