使用Random类的首选方式

4

在Java中,使用Random类的首选方法是什么?

a) 创建一个Random对象,并多次使用它。

b) 每次需要随机值时都创建一个新的Random对象。

有哪些缺点和好处?


1
如果你选择a,那么你会有一些内存开销。如果你选择b,那么你会有性能开销。在这两种情况下,开销取决于你所做的事情,可能是可以忽略的或者显著的。 - nhahtdh
如果你担心生成的数字不够随机,你可以重新设定 Random 对象来解决这个问题 - 这比创建一个全新的对象要简单得多。myRandom.setSeed( System.currentTimeMillis() ); - Jamie
@Jamie,那其实是个不好的主意。因为没有明确的保证结果值流满足相同的随机统计定义。请参考Dave Costa的回答。 - Stefan
3个回答

5
从技术上讲,类所做的保证是单个实例将产生一串伪随机值。使用方法(b)时,并没有明确保证生成的值序列符合相同的统计随机性定义。因此,如果您关心真正的统计随机性,则首选(a)。
我认为(b)没有太多好处。我想这意味着您不需要持有对单个Random实例的引用,但在单例类中执行该操作很简单。通常,出于性能原因,我会谨慎创建大量新对象,但您可以测量影响并决定是否可接受。
因此,在这些选项之间,我通常更喜欢(a)。
我可以看到第三个选项,即使用多个长时间存活的实例。如果您有多个线程,并且希望每个线程使用自己的Random对象,则可以这样做。(从javadoc中不清楚多个线程调用单个对象的含义。)

2
“没有明确的保证,生成的值流满足相同的随机性统计定义。”当使用相同的种子时,这一点尤其正确。 :) (我曾经遇到过这种情况...) - Stefan

3
如果你需要在一个循环中重复生成随机数,那么你可以创建一个Random对象并使用它来生成数字。几乎没有理由为每个随机数创建一个新的Random对象。这样做可能会不必要地降低程序的性能。
如果你偶尔生成随机数,那么每次生成随机数时创建一个新的Random对象也没什么坏处。保留一个Random对象也是可以的。请注意,这可能与上面的情况混合在一起:例如,在游戏开始时可能会生成许多随机数,但在游戏过程中不会发生任何随机事件。
对于Java虚拟机,我对不保留Random对象在整个程序生命周期内可以节省的内存使用量有些怀疑。另一方面,如果总是重新创建Random对象,则肯定会影响性能。这种开销可能可见,也可能不可见,具体取决于程序的操作。

1
这里的其他答案都很好,特别是来自Dave Costa的答案。我只想补充一点。

你想让谁看到随机行为?程序员还是最终用户?

使用一个带有静态种子的Random对象意味着您始终能够执行相同的操作并获得相同的结果(Random是伪随机而不是真正的随机)。这对于调试和尝试重现报告的错误非常有用!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接