Ответ 1
Random
Javadoc говорит:
Экземпляры java.util.Random являются потокобезопасными. Однако одновременное использование одного и того же экземпляра java.util.Random через потоки может столкнуться с конкуренцией и, как следствие, низкой производительностью. Вместо этого используйте ThreadLocalRandom в многопоточных конструкциях.
Random
- это поточно-безопасный объект в силу AtomicLong
, который сохраняет текущее семя, поэтому его использование отменяет большую часть параллельного ускорения, которое является точкой вашего упражнения.
Вместо этого используйте ThreadLocalRandom.getCurrent()
и избегайте, по крайней мере, проблемы с конкуренцией (хотя путем введения накладных расходов на поиск ThreadLocal
). Также используйте SplittableRandom
для извлечения внешнего потока случайных чисел. Эта реализация позволяет произвольный доступ к элементам потока, что является ключом к параллелизуемости goood.
import static java.util.concurrent.ThreadLocalRandom.current;
String getRandomText(int len, double spaceProb) {
return new SplittableRandom().ints(len, 'a', 'z'+1).parallel()
.map(i -> current().nextDouble()<spaceProb ? ' ' : i)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();