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

kha*_*hik 5 java random performance multithreading secure-random

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

让我们对上下文有一些了解:随机值是在HTTP请求处理程序内部生成的,每个请求一个,并且我正在考虑多线程的问题,寻求安全性和性能的最佳组合。

Pet*_*ček 5

这取决于。

创建单个实例显然更简单,并且应该是默认行为。这两个RandomSecureRandom是线程安全的,因此,将工作得很好。首先执行简单而正确的工作,然后根据预期的峰值争用/峰值性能预算来衡量您的效果,并分析结果。

Random

如果您使用的Random是单实例方法太慢,请考虑使用ThreadLocalRandom。JavaDoc Random很好地建议了它的用法:

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

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

我要说的是,在现代的应用程序与池线程,你应该总是使用ThreadLocalRandom代替Random-随机性是一样的,但单线程性能要好得多。

SecureRandom

SecureRandom但是,如果使用,ThreadLocalRandom则不是一种选择。同样,不要猜测,测量!也许使用a的单个共享实例SecureRandom就足够了。用预期的峰值争用进行测试,如果安全随机实例最终成为瓶颈,则仅考虑改善情况的方法。

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

根据您的应用程序,ThreadLocal<SecureRandom>可以选择a。不过,我认为这是一个过大的选择,可能会首选类似于Striped该类的方案(SecureRandom创建并随机访问X 实例以帮助防止竞争)。