Является ли StringBuilder потокобезопасным (используя его с parallelStream)?

Мой код:

StringBuilder sb = new StringBuilder();

events.parallelStream().forEach(event -> {
    sb.append(event.toString());
    sb.append("\n");
});

Мне не нужен порядок events.toString() в конечном результате. Но мне все равно, что events.toString() будет правильно отображаться по одной строке за другой, без смешивания/перебора конечно.

Является ли parallelStream (вместо stream) безопасным в этом отношении?

Ответ 1

Лучшее решение - использовать

events.parallelStream().map(event -> event+"\n").collect(Collectors.joining());

Или в качестве альтернативы (благодаря @Holger):

events.parallelStream().map(Object::toString).collect(Collectors.joining("\n", "", "\n"));

В общем случае избегайте использования forEach в качестве терминальной операции для потоков. Обычно операции сокращения, такие как collect или reduce, являются лучшими альтернативами.

Ответ 2

Нет, он не является потокобезопасным.

Это основное различие между старыми StringBuffer и новыми StringBuilder - первые методы синхронизированы, а последние - нет.

Это не очень полезно сделать так, даже если вы вместо этого использовали бы StringBuffer - потоки должны были бы ждать друг от друга, чтобы записать в StringBuffer.

Ответ 3

Нет, это не так. Как отмечено в его javadoc:

Измененная последовательность символов. Этот класс предоставляет API, совместимый с StringBuffer, но без гарантии синхронизации.

Используйте StringBuffer вместо этого.