(这是在SLES上的Java 8和Tomcat 8,FWIW。)
在我初次播种之后,SecureRandom
(特别是SHA1PRNG
提供商的SUN
算法)对我的性能问题有多担心?我在多个线程中使用单个SecureRandom
实例? SecureRandom
是线程安全的,这意味着某种程度的潜在争用?
我在Java 8 Javadocs中没有看到为SecureRandom
讨论这个问题的任何内容,尽管我发现Random
的Javadocs在使用单个Random
时会特别警告争用和性能下降SecureRandom
1}}跨线程的实例。
我们正在考虑使用单个SecureRandom
实例,因为我们认为在encrypt()
方法(使用SecureRandom
方法中获取新的SecureRandom
实例太昂贵了对于IV生成)因为播种开销会导致你在完成它之前使用新的ThreadLocal<SecureRandom>
非常少的几次。
我们正在考虑让包含encrypt()
方法的类的静态SecureRandom
成员,以便每个线程使用一个ThreadLocal.remove()
。我们故意不致电SecureRandom
,因为如果我们走这条路线,我们实际上会希望实例能够#34;生活&#34;尽可能在tomcat线程中(最小化创建新ThreadLocal
个实例的次数)。
从这里阅读有关ThreadLocal
内存泄漏的消息,我对这种方法有些担忧。但是,我们确实从不重新部署webapp。它用于嵌入式系统,当webapp升级时(这是整个系统升级的一部分,每年只发生几次),Tomcat完全关闭,新的war文件丢失,Tomcat重新启动。这似乎是为了使与webapp相关的SecureRandom
漏洞无法实现。
那么,有没有关于&#34;有争议的&#34; SecureRandom
是,并且就如何在多线程环境中最正确地使用{{1}}达成共识?
答案 0 :(得分:2)
查看SecureRandom
的源代码,它使用synchronized
方法,因此在大多线程环境中有关synchronized
的任何讨论均适用。
鉴于Random
javadoc中的这条说明(如您所述),我说您使用ThreadLocal<SecureRandom>
的计划是恰当的:
java.util.Random
的实例是线程安全的。但是,跨线程同时使用相同的java.util.Random
实例可能会遇到争用并因此导致性能不佳。请考虑在多线程设计中使用ThreadLocalRandom
。
正如您自己总结的那样,您的实施方式不会出现内存泄漏问题。这尤其正确,因为存储在ThreadLocal
中的对象来自系统ClassLoader,而不是您的webapp的ClassLoader。