一尘不染

最大限度地减少多线程环境中的SecureRandom性能问题?

tomcat

(这与SLES和FWIW上的Java 8和Tomcat 8一起使用。)

当我在多个线程中使用单个实例时 在初始播种
我需要担心SecureRandom(特别是提供程序的SHA1PRNG算法SUN)性能问题吗?是线程安全的,所以意味着潜在的争用水平?
__SecureRandom``SecureRandom

我没有看到Java 8 Javadocs讨论此问题,SecureRandom尽管我看到Javadocs
Random确实会Random在跨线程使用单个实例时特别警告争用和性能下降。

我们正在考虑使用单个SecureRandom实例,因为从我们的角度来看,SecureRandom在我们的encrypt()方法中获取新实例(SecureRandom用于IV生成)太昂贵了,因为如果您在使用新实例SecureRandom之前很少使用新实例,那么种子开销会杀死您完成它。

我们也可以考虑使用ThreadLocal<SecureRandom>包含该encrypt()方法的类的静态成员,以便SecureRandom每个线程使用一个。我们故意

打电话,ThreadLocal.remove()因为如果走这条路线,我们实际上希望实例尽可能长时间地“驻留”在tomcat线程中(以最大程度地减少SecureRandom创建新实例的次数)。

通过阅读有关ThreadLocal内存泄漏的信息,我对这种方法有些担忧。但是,我们实际上 从不
重新部署Web应用程序。它用于嵌入式系统中,并且在升级Web应用程序时(这是整个系统升级的一部分,并且每年仅发生几次),Tomcat完全关闭,新的war文件被删除,Tomcat重新启动。这似乎是为了解决与Webapp相关的ThreadLocal漏洞。

因此,是否有关于“争议性”的良好数据SecureRandom,并且在如何SecureRandom在多线程环境中最正确地使用方面是否存在共识?


阅读 447

收藏
2020-06-16

共1个答案

一尘不染

查看的源代码SecureRandom,它使用一种synchronized方法,因此synchronized在多线程环境下进行的任何讨论都适用。

鉴于Random
javadoc中的这一注释(如您所述),我认为您的使用计划ThreadLocal<SecureRandom>是适当的:

的实例java.util.Random是线程安全的。但是,java.util.Random跨线程并发使用同一实例可能会遇到争用并因此导致性能下降。考虑改为ThreadLocalRandom在多线程设计中使用。

总结一下,您的实现不会遇到内存泄漏问题。这尤其如此,因为存储在中的对象ThreadLocal来自系统ClassLoader,而不是来自Webapp的ClassLoader。

2020-06-16