Являются ли сборщики Guava toImmutableSet() и toImmutableList() потокобезопасными?

У Guava есть сборщики, такие как ImmutableSet.toImmutableSet() и ImmutableList.toImmutableList(). Являются ли они потокобезопасными? Безопасно ли использовать их с параллельными потоками?

Насколько я вижу, используются обычные сборщики, которые не являются потокобезопасными:

private static final Collector<Object, ?, ImmutableSet<Object>> TO_IMMUTABLE_SET =
    Collector.of(
        ImmutableSet::<Object>builder,
        ImmutableSet.Builder::add,
        ImmutableSet.Builder::combine,
        ImmutableSet.Builder::build);

С другой стороны, первый и третий параметры Collector.of() вызывают подозрение, что JDK может создать отдельный построитель для каждого параллельного потока и объединить их результат, чтобы сделать его потокобезопасным.


person palacsint    schedule 20.10.2020    source источник
comment
Кажется, что да, так как они extending из ImmutableCollection, что является потокобезопасным. guava.dev/releases/19.0/api/ документы/com/google/common/collect/   -  person Aman    schedule 20.10.2020
comment
@Aman Нет, не совсем — ImmutableCollection#Builder (и его подклассы), которые используются в TO_IMMUTABLE_SET Collector, не расширяют ImmutableCollection. См. этот вопрос.   -  person Xaerxess    schedule 20.10.2020
comment
@Xaerxess спасибо, я не знал, что он использует конструктор. Понятно, что строители не являются потокобезопасными.   -  person Aman    schedule 20.10.2020
comment
Все правильно реализованные коллекторы являются потокобезопасными при правильном использовании. Вам не нужно гадать по параметрам, как предполагается использовать коллектор. Для этого предназначена документация. . Также есть раздел в документация по пакету.   -  person Holger    schedule 20.10.2020


Ответы (1)


Я считаю, что ответ на вопрос, который вы должны задать, отличается от того, что вы на самом деле задали.

Нет, сборщики не являются потокобезопасными сами по себе (например, построитель ImmutableList выполняет несинхронизированные операции с Object[]), но, что более важно, коллекторы не обязательно должны быть потокобезопасными, чтобы их можно было использовать для параллельных потоковых операций. Для этого см. ответ Стюарта Маркса на вопрос о параллельных потоках, сборщиках и безопасности потоков :

Можно ли безопасно использовать неконкурентные сборщики с параллельным потоком или следует использовать только параллельные версии при сборе из параллельного потока?

Безопасно использовать непараллельный сборщик в операции сбора параллельного потока.

Для получения более подробной информации, пожалуйста, прочитайте ответ и ссылки на документацию/контракты различных java.util.stream классов.

person Xaerxess    schedule 20.10.2020