SecureRandom线程安全吗?

Yis*_*hai 97 java thread-safety

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

eri*_*son 100

是的.它扩展了Random,它始终具有事实上的线程安全实现,并且从Java 7中明确地保证了线程的安全性.

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

  • 请记住,ThreadLocalRandom非常容易破解,因此如果您计划向世界公开生成的值,请使用SecureRandom而不是http://jazzy.id.au/default/2010/09/20/cracking_random_number_generators_part_1.html (8认同)
  • 初始化`SecureRandom`不仅速度慢,而且由于缺少熵而可能会挂起 (4认同)
  • 感谢更新.奇怪的是,该错误标记为"将无法修复".但无论如何他们还是修好了.哦,我不羡慕他们的bug数据库的大小. (3认同)
  • 我要在这里走出去,说这个答案不正确。保证线程安全的Random合同对子类没有约束。当然,随机记录的所有其他属性都不会绑定到子类上,因此我不明白为什么应该假定线程安全。 (2认同)
  • @JamesKPolk未能保留超类型的属性会违反替代性原则. (2认同)
  • @Algiz确实如此,任何代码都可能存在导致其故障的错误。但是,“没有类是线程安全的,因为你不能保证没有错误”并不是一个有用的答案。在我找到一个广泛使用的非线程安全的“SecureRandom”实现之前,我相信这个答案对于任何实际情况都是正确的。 (2认同)
  • 至少在JDK 10中,SecureRandom基于提供程序并检查提供程序是否是线程安全的,如果不是,则在nextBytes中进行同步.因此,虽然子类可能会覆盖该行为,但它是愚蠢的,而替代算法应该是提供者而不是子类. (2认同)

Mat*_*ail 11

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

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

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

    SecureRandom rnd = ...;

    byte[] b = new byte[NRANDOM_BYTES];
    synchronized (rnd) {
        rnd.nextBytes(b);
    }
Run Code Online (Sandbox Code Playgroud)

  • 至少在JDK 10中,SecureRandom基于提供程序,并检查提供程序是否是线程安全的,仅在nextBytes中进行同步(如果不是)。 (3认同)