Java SecureRandom 线程安全吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1461568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:31:27  来源:igfitidea点击:

Is SecureRandom thread safe?

javathread-safety

提问by Yishai

Is SecureRandomthread safe? That is, after initializing it, can access to the next random number be relied on to be thread safe? Examining the source code seems to show that it is, and this bug reportseems to indicate that its lack of documentation as thread safe is a javadoc issue. Has anyone confirmed that it is in fact thread safe?

SecureRandom线程安全的?也就是说,初始化之后,是否可以依赖访问下一个随机数是线程安全的?检查源代码似乎表明它是,并且这个错误报告似乎表明它缺乏作为线程安全的文档是一个 javadoc 问题。有没有人确认它实际上是线程安全的?

采纳答案by erickson

Yes, it is. It extends Random, which always had a de factothreadsafe implementation, and, from Java 7, explicitly guarantees threadsafety.

是的。它 extends Random,它始终具有事实上的线程安全实现,并且从Java 7 开始,明确保证线程安全。

If many threads are using a single SecureRandom, there might be contention that hurts performance. On the other hand, initializing a SecureRandominstance can be relatively slow. Whether it is best to share a global RNG, or to create a new one for each thread will depend on your application. The ThreadLocalRandomclass could be used as a pattern to provide a solution that supports SecureRandom.

如果多个线程使用单个SecureRandom,则可能存在损害性能的争用。另一方面,初始化SecureRandom实例可能相对较慢。最好是共享一个全局 RNG,还是为每个线程创建一个新的 RNG 将取决于您的应用程序。的ThreadLocalRandom类可以被用作图案,以提供一个解决方案,支持SecureRandom

回答by Matt Quail

The current implementation of SecureRandomis thread safe, specifically the two mutating methods nextBytes(bytes[])and setSeed(byte[])are synchronized.

的当前实现SecureRandom是线程安全的,特别是两个 mutating 方法nextBytes(bytes[])并且setSeed(byte[])是同步的。

Well, as far as I've been able to tell, all mutating methods are eventually routed through those two methods, and SecureRandomoverrides a few methods in Randomto ensure that. Which works but could be brittle if the implementation is changed in the future.

好吧,据我所知,所有变异方法最终都通过这两个方法进行路由,并SecureRandom覆盖了一些方法Random以确保这一点。这可行,但如果将来更改实施,则可能会很脆弱。

The best solution is to manually synchronize on the SecureRandominstance first. This means each call stack will acquire two locks on the same object, but that is usually very cheap on modern JVMs. That is, there is not much harm in explicitly synchronizing yourself. For example:

最好的解决方案是先在SecureRandom实例上手动同步。这意味着每个调用堆栈将获取同一对象上的两个锁,但这在现代 JVM 上通常非常便宜。也就是说,明确地同步自己并没有太大的害处。例如:

    SecureRandom rnd = ...;

    byte[] b = new byte[NRANDOM_BYTES];
    synchronized (rnd) {
        rnd.nextBytes(b);
    }