Повторное использование экземпляра java.util.Random против создания нового экземпляра каждый раз - PullRequest
0 голосов
/ 16 октября 2018

Заголовок в значительной степени обобщает его - мы можем создать один экземпляр java.util.Random (или SecureRandom) и использовать его каждый раз, когда нам нужно случайное значение, или мы можем создавать новый экземпляр каждый раз по требованию.Хотите знать, какой из них является предпочтительным способом и почему?

Чтобы дать некоторое представление о контексте: случайное значение генерируется внутри обработчика HTTP-запроса, по одному на запрос, и яВ поисках лучшей комбинации безопасности и производительности, учитывая многопоточность.

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Если вам нужны случайные числа для защиты информации, подойдет только криптографический ГСЧ (например, java.security.SecureRandom).А для любой криптографической ГСЧ простейший подход состоит в том, чтобы использовать только один поточно-ориентированный экземпляр для всего приложения (обратите внимание, что SecureRandom является поточно-ориентированным в соответствии с документацией);Как правило, создание нескольких экземпляров криптографического ГСЧ бесполезно, поскольку все они в конечном итоге должны быть инициализированы данными с высокой энтропией («непредсказуемым»).

Сбор таких «непредсказуемых» данных не является тривиальным , и, по крайней мере, для вашего приложения вам не нужно беспокоиться об этом, когда вы используете SecureRandom, который в основном делает это для вас и включает в себяsetSeed метод, который вы можете использовать для добавления дополнительных данных, чтобы дополнить их случайность.

0 голосов
/ 16 октября 2018

Это зависит.

Создание отдельного экземпляра, очевидно, проще и должно быть поведением по умолчанию.И Random, и SecureRandom являются поточно-ориентированными и поэтому будут работать очень хорошо.Сначала выполните простую и правильную работу, а затем оцените свою производительность по сравнению с ожидаемым пиком конкуренции / пика и проанализируйте результаты.

Random

Если вы используете Random и подход с одним экземпляром слишком медленный, рассмотрите возможность использования ThreadLocalRandom, если это возможно.JavaDoc в Random предлагает его использование:

Экземпляры java.util.Random являются поточно-ориентированными.Однако одновременное использование одного и того же экземпляра java.util.Random в разных потоках может привести к конфликту и, как следствие, к низкой производительности.Вместо этого рассмотрите возможность использования ThreadLocalRandom в многопоточных проектах.

Это создаст только экземпляр для каждого потока, обращающегося к нему.Стоимость создания экземпляра Random / ThreadLocalRandom не является безумной, но она выше, чем создание "нормального" объекта, поэтому вам, вероятно, следует избегать создания нового экземпляра для каждого входящего запроса.Создание одного на поток, как правило, приятное место.

Я бы сказал, что в современных приложениях с пулами потоков вы почти всегда должны использовать ThreadLocalRandom вместо Random - случайность одинакова, нопроизводительность однопоточности намного лучше.

SecureRandom

Если вы используете SecureRandom, то ThreadLocalRandom не вариант.Опять не угадал, измерим!Возможно, будет достаточно использовать один общий экземпляр SecureRandom.Протестируйте с ожидаемым максимальным уровнем конкуренции, и если безопасный случайный экземпляр окажется узким местом, только тогда подумайте о способах улучшения ситуации.

Создание экземпляра SecureRandom очень дорого, так что вы абсолютноне хотите создавать один для каждого входящего запроса.

В зависимости от вашего приложения, опция ThreadLocal<SecureRandom> может быть опцией.Тем не менее, я думаю, что это излишнее, и схема, подобная классу Striped (с экземплярами X SecureRandom, созданными и доступными случайным образом для предотвращения конфликтов), может быть предпочтительнее.

...