先看代码:

public class MySeed {
    public static void main(String[] args) {
        Random random=new Random(100);
        for(int i=0;i<5;i++){
            System.out.println(new Random(100).nextInt(9999));
        }
        System.out.println("===============");
        for(int i=0;i<5;i++){
            System.out.println(random.nextInt(9999));
        }
    }
}

输出:
8980
8980
8980
8980
8980
===============
8980
4033
9748
9720
7576
解释:
用一个固定的种子值来生成的随机数的值是有固定序列的。
1、第一个for中每次一个新Random对象,这个对象生成的第一个随机数始终为8980.
2、第二个for中使用一个对象,生成5个随机数,随机数的值和顺序也是固定的。
这段代码无论执行多少次,得到的值都是一样。

所以在取随机数时,种子应该是动态的。一般建议不传种子,那也就是使用new Random()。

public Random() {
    this(seedUniquifier() ^ System.nanoTime());
}

private static long seedUniquifier() {
    for (;;) {
        long current = seedUniquifier.get();
        long next = current * 181783497276652981L;
        if (seedUniquifier.compareAndSet(current, next))
            return next;
    }
}

网上的一段对随机数的解读:
根c/C++类似,所有标准库提供的Random函数其实都是假Random,真正的Random函数式不需要Seed的。
所谓假Random,是指所返回的随机数字其实是一个稳定算法所得出的稳定结果序列,而不是真正意义上的随机序列。 Seed就是这个算法开始计算的第一个值。所以就会出现只要seed是一样的,那么后续所有“随机”结果和顺序也都是完全一致的。 通常情况下,你可以用 DateTime.Now.Millisecend() 也就是当前始终的毫秒来做Seed .因为毫秒对你来说是一个1000以内的随即数字。 这样可以大大改善保准库的Random结果的随机性。 不过这仍然算不上是完全随机,因为重复的概率还是千分之一。

另外需要注意的是,如果一直调用标准库Random,那么在调用了N次以后,输出结果就会循环最开始的序列了。也就是说,标准库Random所能生成的不同结果的个数也是有限的。32位系统一般也就是几万次以后就会出现重复。

https://social.msdn.microsoft.com/Forums/zh-CN/77ce649a-7fc5-4d17-94d7-d4f8be8e5ad8/randomseed?forum=visualcshartzhchs

Leave a reply

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

required

thirty − twenty seven =