SecureRandom
线程是否安全?也就是说,在初始化之后,可以访问依赖的下一个随机数是线程安全的吗?检查源代码似乎表明它是,并且this bug report似乎表明它缺乏作为线程安全的文档是一个javadoc问题。有没有人证实它实际上是线程安全的?
答案 0 :(得分:97)
是的,确实如此。它扩展了Random
,它始终具有事实上的线程安全实现,并且来自Java 7, explicitly guarantees threadsafety.
如果许多线程使用单个SecureRandom
,则可能存在损害性能的争用。另一方面,初始化SecureRandom
实例可能相对较慢。是否最好共享全局RNG,或者为每个线程创建一个新RNG取决于您的应用程序。 ThreadLocalRandom
类可用作模式,以提供支持SecureRandom
的解决方案。
答案 1 :(得分:11)
SecureRandom
的当前实现是线程安全的,特别是两个变异方法nextBytes(bytes[])
和setSeed(byte[])
是同步的。
好吧,据我所知,所有变异方法最终都会通过这两种方法进行路由,而SecureRandom
会覆盖Random
中的一些方法来确保这一点。如果将来改变实施,哪个有效但可能很脆弱。
最佳解决方案是首先在SecureRandom
实例上手动同步。这意味着每个调用堆栈将在同一对象上获取两个锁,但这在现代JVM上通常非常便宜。也就是说,明确同步自己并没有太大的危害。例如:
SecureRandom rnd = ...;
byte[] b = new byte[NRANDOM_BYTES];
synchronized (rnd) {
rnd.nextBytes(b);
}