Является ли Collectors.joining( "," ) потокобезопасным?

Реализуются ли реализации java.util.stream.Collectors::joining потокобезопасными? Могу ли я сделать что-то вроде

public final class SomeClass {
  private static final Collector<CharSequence, ?, String> jc = Collectors.joining(",");

  public String someMethod(List<String> someList) {
       return someList.parallelStream().collect(jc);
  }
}

не опасаясь столкнуться с проблемами concurrency?

Ответ 1

Вы можете использовать этот коллекционер как любой другой сборщик, предоставляемый в классе Collectors, не опасаясь запусков в concurrency. Collector не нужно заботиться о безопасности потоков, если у него нет характеристики CONCURRENT. Ему просто нужно, чтобы его операции не мешали, апатриды и ассоциативные. Остальное будет сделано самим трубопроводом Stream. Он будет использовать функции коллектора таким образом, чтобы не требовать дополнительной синхронизации. В частности, когда вызывается функция accumulator или combiner, она гарантирует, что ни один другой поток не будет работать с одним и тем же накопленным значением на данный момент. Это указано в Collector:

Библиотеки, реализующие сокращение на основе Collector, например Stream.collect(Collector), должны придерживаться следующих ограничений:

<... >

  • Для неконкурентных коллекционеров любой результат, возвращаемый функциями поставщика результата, аккумулятора или объединителя, должен быть последовательно ограниченным потоком. Это позволяет собирать коллекцию параллельно, если Collector не требуется выполнить какую-либо дополнительную синхронизацию. Реализация сокращения должна управлять тем, что вход правильно разбит на разделы, что разделы обрабатываются изолированно, а объединение происходит только после завершения накопления.

Обратите внимание, что сам сборщик является апатридом, а также функциями, которые он предоставляет, поэтому он также безопасен для использования в статическом поле. Состояние сохраняется во внешнем аккумуляторе, который возвращается supplier и возвращается обратно в accumulator, combiner и finisher. Поэтому, даже если один и тот же коллектор повторно используется несколькими потоковыми операциями, они не мешают.