Using Random Number Generator with Current Time vs Without

末鹿安然 提交于 2019-12-23 09:34:58

问题


I want to understand what the difference is between using a Random number generator with System.currentTimeMillis() as the seed and just using the default constructor. That is, what is the difference between this:

Random rand = new Random(System.currentTimeMillis());

and this:

Random rand = new Random();

I know that the numbers are pseudo-random, but I am yet to fully understand the details, and how they come about, between the level of 'randomness' one gets when current time is used as seed, and when the default constructor is used.


回答1:


If you want your random sequences to be the same between runs you can specify a seed. Usually you don't want that to happen so you use a different seed for every run and System.currentTimeMillis() is reasonable seed commonly used. If you are facing something multithreded where multiple threads will initialize the RNG at the same time you may want to avoid using System.currentTimeMillis() and let Java use its own initialization.




回答2:


Supplying your own seed is useful for simulations where you purposely want to generate the same sequence of pseudorandom values multiple times. In general, though, it's just as well to use the default constructor.

When the default constructor is used, the docs say:

This constructor sets the seed of the random number generator to a value very likely to be distinct from any other invocation of this constructor.

In other words, it generates its own seed internally. The details depend on the particular Java implementation being used. One implementation I've seen has this:

private static volatile long seedBase = 0;

public Random() {
    setSeed(System.nanoTime() + seedBase);
    ++seedBase;
}

The actual quality of the randomness doesn't change. If the quality of the random sequence is of concern to you, you can also use java.security.SecureRandom, which has better cryptographic behavior. (See, e.g., this thread.)




回答3:


If you look into the implementation of the default constructor of Random, you can see that it uses System.nanoTime() internally. In addition, it uses a seed 'uniquifier' to make subsequent seeds even more distinct. This, however, requires access to a static final AtomicLong. Thus if you have a highly concurrent application where many threads are constructing Random instances, it might be better to not use the default constructor to avoid contention on the seed generation. If you want to guarantee that two threads can never get the same seed you should take the default constructor. This said, in practice, in 99% of the cases, it will be irrelevant which variant you take.

As Ted Hopp correctly states, the behavior of the default constructor depends on the concrete JDK implementation and also varies between Java versions.

Also see Contention in concurrent use of java.util.Random for another contention issue with the Random class.



来源:https://stackoverflow.com/questions/32277110/using-random-number-generator-with-current-time-vs-without

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!