Вопрос по thread-safety, java – Безопасно ли защищать поток SecureRandom?

92

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

Ваш Ответ

2   ответа
11

SecureRandom является потокобезопасным, в частности, два метода мутацииnextBytes(bytes[]) а такжеsetSeed(byte[]) синхронизированы.

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

Лучшее решение - вручную синхронизировать наSecureRandom экземпляр первый. Это означает, что каждый стек вызовов получает две блокировки для одного и того же объекта, но это обычно очень дешево на современных JVM. То есть нет особого вреда в явной синхронизации себя. Например:

    SecureRandom rnd = ...;

    byte[] b = new byte[NRANDOM_BYTES];
    synchronized (rnd) {
        rnd.nextBytes(b);
    }
java.security.SecureRandom#nextBytes в Java 8 не синхронизируется. Не могли бы вы указать, в какой версии Java вы нашли синхронизированный#nextBytes?. Jaime Hablutzel
По крайней мере, в JDK 10 SecureRandom основан на провайдере и проверяет, является ли провайдер безопасным для потоков, только синхронизирует, если это не так, в nextBytes. nafg
93

Random, который всегда былде-факто потокобезопасная реализация, и, отJava 7 явно гарантирует безопасность потоков.

Если много потоков используют одинSecureRandom, может быть раздор, который вредит производительности. С другой стороны, инициализацияSecureRandom экземпляр может быть относительно медленным. Будет ли лучше разделить глобальный ГСЧ или создать новый для каждого потока, будет зависеть от вашего приложения.ThreadLocalRandom класс может быть использован в качестве шаблона, чтобы обеспечить решение, которое поддерживаетSecureRandom.

инициализацияSecureRandom может не только быть медленным, но потенциально может зависнуть из-за отсутствия энтропии Walter Tross
Помните, что ThreadLocalRandom очень легко взломать, поэтому, если вы планируете представить сгенерированное значение миру, используйте вместо него SecureRandom.jazzy.id.au/default/2010/09/20/... walv
@JamesKPolk Неспособность сохранить свойство супертипа нарушит принцип подстановки. erickson
Я собираюсь выйти на конечности здесь и сказать, что этот ответ неверен. Контракт для Random, который гарантирует безопасность потоков, не является обязательным для подклассов. Конечно, все остальные документированные свойства Random не являются обязательными для подклассов, поэтому я не понимаю, почему следует предполагать безопасность потоков. James K Polk
Спасибо за обновления. Как ни странно, ошибка помечена как закрытая как "не исправит". Но они все равно это исправили. О, хорошо, я не завидую им размер их базы данных ошибок. Yishai

Похожие вопросы