java 随机数种子
引子:需要實(shí)現(xiàn)每天隨機(jī)獲得一個(gè)禮包,且全服玩家隨出來的都是同一個(gè)。
實(shí)現(xiàn)方案:以當(dāng)前時(shí)間是一年的第幾天作為random的種子,取1~禮包總個(gè)數(shù)范圍內(nèi)的隨機(jī)值。
public static int getBuffId() {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.nanoTime());
int dateInYear = c.get(Calendar.DAY_OF_YEAR);
return new Random(dateInYear).nextInt(10) + 1;
}
于是決定深入了解一下隨機(jī)數(shù)的種子。
Random兩種構(gòu)造方法。一種是無(wú)參構(gòu)造函數(shù)。種子是++seedUniquifier + System.nanoTime(), 所以每新new一個(gè)Random實(shí)例,種子都會(huì)變。
private static volatile long seedUniquifier = 8682522807148012L;
public Random() { this(++seedUniquifier + System.nanoTime()); }
另一種是設(shè)置種子的構(gòu)造方法。
public Random(long seed) {
this.seed = new AtomicLong(0L);
setSeed(seed);
}
看一下next()方法。每次調(diào)用next()方法。種子就會(huì)發(fā)生變化nextseed = (oldseed * multiplier + addend) & mask;
private final static long multiplier = 0x5DEECE66DL; private final static long addend = 0xBL; private final static long mask = (1L << 48) - 1;
protected int next(int bits) { long oldseed, nextseed; AtomicLong seed = this.seed; do { oldseed = seed.get(); nextseed = (oldseed * multiplier + addend) & mask; } while (!seed.compareAndSet(oldseed, nextseed));//保證oldseed跟nextseed不相同 return (int)(nextseed >>> (48 - bits)); }
public int nextInt() { return next(32); }
實(shí)例:
//實(shí)例1
Random random = new Random(1000);
for (int i = 1; i < 4; i++) {
System.out.println(random.nextInt());
}
System.out.println("...........");
//實(shí)例2
for (int j = 0; j < 4; j++) {
System.out.println(new Random(1000).nextInt());
}
運(yùn)行結(jié)果:
1487836800000 -1244746321 1060493871 -1826063944 ........... -1244746321 -1244746321 -1244746321 -1244746321
分析:運(yùn)行結(jié)果不一樣。原因如下:
實(shí)例1設(shè)定了種子1000,for循環(huán)里,nextSeed一直在變,所以隨出來的值也每次不一樣。
實(shí)例2每次new一個(gè)新的Random對(duì)象,每次seed都會(huì)被重置成1000,后面調(diào)用nextInt() 算出來的nextSeed都是同一個(gè)值,所以不管循環(huán)幾次,隨出來的結(jié)果都一樣。
總結(jié)
以上是生活随笔為你收集整理的java 随机数种子的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: apache poi使用例_GitHub
- 下一篇: Linux "零拷贝"