java - 重用 java.util.Random 实例与每次都创建一个新实例

标签 java multithreading performance random secure-random

标题几乎概括了它 - 我们可以创建一个 java.util.Random(或 SecureRandom)的实例,并在每次需要随机值时使用它或我们可以每次按需创建一个新实例。想知道哪种方法是首选,为什么?

给出一些关于上下文的想法:随机值是在 HTTP 请求处理程序中生成的,每个请求一个,我正在寻找考虑多线程的安全性和性能的最佳组合。

最佳答案

视情况而定。

创建单个实例显然更简单,应该是默认行为。两者 RandomSecureRandom是线程安全的,因此可以正常工作。首先做简单而正确的事情,然后根据预期的峰值争用/峰值性能预算衡量您的性能,并分析结果。

Random

如果您使用 Random并且单实例方法太慢,考虑使用 ThreadLocalRandom如果可能的话。 Random 中的 JavaDoc很好地建议了它的用法:

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.

它只会为访问它的每个线程创建一个实例。 Random 的创建成本/ThreadLocalRandom instance 并不疯狂,但它高于创建“普通”对象,因此您应该避免为每个传入请求创建一个新实例。为每个线程创建一个通常是一个不错的最佳选择。

我想说的是,在使用线程池的现代应用程序中,您应该几乎总是使用 ThreadLocalRandom而不是 Random - 随机性相同,但单线程性能要好得多。

SecureRandom

如果您使用 SecureRandom , 虽然, ThreadLocalRandom不是一个选项。再次强调,不要猜测,要测量!也许使用一个 SecureRandom 的共享实例会足够好。用您预期的峰值竞争进行测试,如果安全随机实例被证明是瓶颈,那么才考虑改善这种情况的方法。

创建 SecureRandom实例的成本非常高,因此您绝对不想为每个传入请求都创建一个实例。

根据您的应用,ThreadLocal<SecureRandom>可能是一个选择。不过,我认为这是一种矫枉过正,并且类似于 Striped 的方案。类(随机创建和访问 X SecureRandom 实例以帮助防止争用)可能是首选。

关于java - 重用 java.util.Random 实例与每次都创建一个新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52838533/

相关文章:

java - Lucene 能否从单个索引文件返回多个搜索结果?

c# - 快速查找字典文本文件中是否存在单词

javascript - JS 脚本加载与 HTML 中的 &lt;script&gt; 标签

java - Kafka Avro 序列化程序 : org. apache.avro.AvroRuntimeException:未打开

java - 什么是NullPointerException,我该如何解决?

java - 从 csv 文件打印特定行

c++ - 提高opencl的性能

C++:如何读取大文本文件并更快地保存到数组

Java 网络 - 在同一线程中的不同端口上并行启动多个服务器套接字

java - 访问 JMH 状态