(这与SLES和FWIW上的Java 8和Tomcat 8一起使用。)
当我在多个线程中使用单个实例时 , 在初始播种 后 我需要担心SecureRandom(特别是提供程序的SHA1PRNG算法SUN)性能问题吗?是线程安全的,所以意味着潜在的争用水平? __SecureRandom``SecureRandom
SecureRandom
SHA1PRNG
SUN
SecureRandom``SecureRandom
我没有看到Java 8 Javadocs讨论此问题,SecureRandom尽管我看到Javadocs Random确实会Random在跨线程使用单个实例时特别警告争用和性能下降。
Random
我们正在考虑使用单个SecureRandom实例,因为从我们的角度来看,SecureRandom在我们的encrypt()方法中获取新实例(SecureRandom用于IV生成)太昂贵了,因为如果您在使用新实例SecureRandom之前很少使用新实例,那么种子开销会杀死您完成它。
encrypt()
我们也可以考虑使用ThreadLocal<SecureRandom>包含该encrypt()方法的类的静态成员,以便SecureRandom每个线程使用一个。我们故意 不 打电话,ThreadLocal.remove()因为如果走这条路线,我们实际上希望实例尽可能长时间地“驻留”在tomcat线程中(以最大程度地减少SecureRandom创建新实例的次数)。
ThreadLocal<SecureRandom>
ThreadLocal.remove()
通过阅读有关ThreadLocal内存泄漏的信息,我对这种方法有些担忧。但是,我们实际上 从不 重新部署Web应用程序。它用于嵌入式系统中,并且在升级Web应用程序时(这是整个系统升级的一部分,并且每年仅发生几次),Tomcat完全关闭,新的war文件被删除,Tomcat重新启动。这似乎是为了解决与Webapp相关的ThreadLocal漏洞。
ThreadLocal
因此,是否有关于“争议性”的良好数据SecureRandom,并且在如何SecureRandom在多线程环境中最正确地使用方面是否存在共识?
查看的源代码SecureRandom,它使用一种synchronized方法,因此synchronized在多线程环境下进行的任何讨论都适用。
synchronized
鉴于Random javadoc中的这一注释(如您所述),我认为您的使用计划ThreadLocal<SecureRandom>是适当的:
的实例java.util.Random是线程安全的。但是,java.util.Random跨线程并发使用同一实例可能会遇到争用并因此导致性能下降。考虑改为ThreadLocalRandom在多线程设计中使用。
java.util.Random
ThreadLocalRandom
总结一下,您的实现不会遇到内存泄漏问题。这尤其如此,因为存储在中的对象ThreadLocal来自系统ClassLoader,而不是来自Webapp的ClassLoader。