在多线程环境中最小化SecureRandom性能问题?

时间:2015-12-17 17:08:45

标签: java multithreading tomcat encryption thread-local

(这是在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}}达成共识?

1 个答案:

答案 0 :(得分:2)

查看SecureRandom的源代码,它使用synchronized方法,因此在大多线程环境中有关synchronized的任何讨论均适用。

鉴于Random javadoc中的这条说明(如您所述),我说您使用ThreadLocal<SecureRandom>的计划是恰当的:

  

java.util.Random的实例是线程安全的。但是,跨线程同时使用相同的java.util.Random实例可能会遇到争用并因此导致性能不佳。请考虑在多线程设计中使用ThreadLocalRandom

正如您自己总结的那样,您的实施方式不会出现内存泄漏问题。这尤其正确,因为存储在ThreadLocal中的对象来自系统ClassLoader,而不是您的webapp的ClassLoader。