最小化多线程环境中的 SecureRandom 性能问题?
Minimizing SecureRandom performance problems in multithreaded environment?
(这是在 SLES,FWIW 上使用 Java 8 和 Tomcat 8。)
我需要多担心 SecureRandom
的性能问题(特别是 SUN
提供程序的 SHA1PRNG
算法)after当我在多个线程中使用单个 SecureRandom
实例时的初始播种? SecureRandom
是线程安全的,所以这意味着一定程度的潜在争用?
我在 Java 8 Java 文档中没有看到任何关于 SecureRandom
的讨论,尽管我看到 Java Random
的文档在跨线程使用单个 Random
实例时,专门 warn 处理争用和性能下降问题。
我们正在考虑使用单个 SecureRandom
实例,因为据我们所知,在我们的 encrypt()
方法(使用 SecureRandom
用于 IV 代)因为如果你在完成之前使用新的 SecureRandom
几次,那么播种开销会杀死你。
我们正在考虑让 class 的静态 ThreadLocal<SecureRandom>
成员包含 encrypt()
方法,以便每个线程使用一个 SecureRandom
。我们会故意 不 调用 ThreadLocal.remove()
因为如果我们走这条路,我们实际上希望 tomcat 线程中的实例尽可能长(以尽量减少创建新 SecureRandom
实例的次数)。
从这里阅读有关 ThreadLocal
内存泄漏的信息,我对这种方法有些担忧。但是,我们确实 从未 重新部署 web 应用程序。它用于嵌入式系统,当 webapp 升级时(这是整个系统升级的一部分,一年只发生几次)Tomcat 完全关闭,新的 war 文件被丢弃下来,Tomcat 重新启动。这似乎是为了让与 webapp 相关的 ThreadLocal
泄漏变得毫无意义。
那么,是否有任何关于 "contentious" SecureRandom
的好数据,并且是否就如何在重度多线程环境中最正确地使用 SecureRandom
达成共识?
查看 SecureRandom
的源代码,它使用 synchronized
方法,因此任何关于 synchronized
在重度多线程环境中的讨论都是适用的。
鉴于 Random
javadoc 中的这条注释(如您所述),我认为您使用 ThreadLocal<SecureRandom>
的计划是合适的:
Instances of java.util.Random
are threadsafe. However, the concurrent use of the same java.util.Random
instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom
in multithreaded designs.
正如您自己总结的那样,您的实现不会出现内存泄漏问题。尤其如此,因为存储在 ThreadLocal
中的对象来自系统 ClassLoader,而不是您的 webapp 的 ClassLoader。
(这是在 SLES,FWIW 上使用 Java 8 和 Tomcat 8。)
我需要多担心 SecureRandom
的性能问题(特别是 SUN
提供程序的 SHA1PRNG
算法)after当我在多个线程中使用单个 SecureRandom
实例时的初始播种? SecureRandom
是线程安全的,所以这意味着一定程度的潜在争用?
我在 Java 8 Java 文档中没有看到任何关于 SecureRandom
的讨论,尽管我看到 Java Random
的文档在跨线程使用单个 Random
实例时,专门 warn 处理争用和性能下降问题。
我们正在考虑使用单个 SecureRandom
实例,因为据我们所知,在我们的 encrypt()
方法(使用 SecureRandom
用于 IV 代)因为如果你在完成之前使用新的 SecureRandom
几次,那么播种开销会杀死你。
我们正在考虑让 class 的静态 ThreadLocal<SecureRandom>
成员包含 encrypt()
方法,以便每个线程使用一个 SecureRandom
。我们会故意 不 调用 ThreadLocal.remove()
因为如果我们走这条路,我们实际上希望 tomcat 线程中的实例尽可能长(以尽量减少创建新 SecureRandom
实例的次数)。
从这里阅读有关 ThreadLocal
内存泄漏的信息,我对这种方法有些担忧。但是,我们确实 从未 重新部署 web 应用程序。它用于嵌入式系统,当 webapp 升级时(这是整个系统升级的一部分,一年只发生几次)Tomcat 完全关闭,新的 war 文件被丢弃下来,Tomcat 重新启动。这似乎是为了让与 webapp 相关的 ThreadLocal
泄漏变得毫无意义。
那么,是否有任何关于 "contentious" SecureRandom
的好数据,并且是否就如何在重度多线程环境中最正确地使用 SecureRandom
达成共识?
查看 SecureRandom
的源代码,它使用 synchronized
方法,因此任何关于 synchronized
在重度多线程环境中的讨论都是适用的。
鉴于 Random
javadoc 中的这条注释(如您所述),我认为您使用 ThreadLocal<SecureRandom>
的计划是合适的:
Instances of
java.util.Random
are threadsafe. However, the concurrent use of the samejava.util.Random
instance across threads may encounter contention and consequent poor performance. Consider instead usingThreadLocalRandom
in multithreaded designs.
正如您自己总结的那样,您的实现不会出现内存泄漏问题。尤其如此,因为存储在 ThreadLocal
中的对象来自系统 ClassLoader,而不是您的 webapp 的 ClassLoader。