【问题标题】:Minimizing SecureRandom performance problems in multithreaded environment?最小化多线程环境中的 SecureRandom 性能问题?
【发布时间】:2016-03-24 06:18:25
【问题描述】:

(这是在 SLES 上使用 Java 8 和 Tomcat 8,FWIW。)

当我使用单个 @987654324 时,我需要对SecureRandom(特别是SHA1PRNG 提供程序的SHA1PRNG 算法)的性能问题感到多担心在初始播种之后@实例在多个线程中? SecureRandom 是线程安全的,所以这意味着某种程度的潜在争用?

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

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

我们还考虑在包含encrypt() 方法的类中添加一个静态ThreadLocal<SecureRandom> 成员,以便每个线程使用一个SecureRandom。我们会有意不调用ThreadLocal.remove(),因为如果我们走这条路线,我们实际上希望实例尽可能长时间地“生活”在tomcat线程中(以尽量减少新SecureRandom的次数实例已创建)。

从这里阅读有关ThreadLocal 内存泄漏的信息,我对这种方法有些担忧。但是,我们确实从不重新部署 web 应用程序。它用于嵌入式系统,当 webapp 升级时(这是整个系统升级的一部分,一年只发生几次)Tomcat 完全关闭,新的 war 文件下降,Tomcat 重新启动。这似乎会使与 webapp 相关的ThreadLocal 泄漏毫无意义。

那么,关于SecureRandom 的“争议性”有多“有争议”,是否有任何好的数据,对于如何在多线程环境中最恰当地使用SecureRandom 是否达成了共识?

【问题讨论】:

  • 您确定播种开销会杀死您吗?我希望它在 /dev/urandom 用于播种的 Linux 环境中相当快。此外,您在加密方法中加密的典型消息有多大?毕竟单个 SecureRandom 实例的争用可能并不多。

标签: java multithreading tomcat encryption thread-local


【解决方案1】:

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

鉴于Random javadoc 中的这条注释(正如您所提到的),我想说您使用ThreadLocal<SecureRandom> 的计划是合适的:

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

正如您自己得出的结论,您的实现不会出现内存泄漏问题。尤其如此,因为ThreadLocal 中存储的对象来自系统 ClassLoader,而不是您的 webapp 的 ClassLoader。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-08
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 2014-01-20
    • 1970-01-01
    相关资源
    最近更新 更多