还是看看Random的源码吧,首先是3个常量: private final static long multiplier = 0x5DEECE66DL //十进制是25214903917;
 private final static long addend = 0xBL //十进制是11;
 private final static long mask = (1L << 48) - 1//十进制是281474976710655,十六进制是0xffffffffffff;然后是构造方法和setSeed:public Random(long seed) {
        this.seed = new AtomicLong(0L);
        setSeed(seed);
    }
synchronized public void setSeed(long seed) {
        seed = (seed ^ multiplier) & mask;
        this.seed.set(seed);
     haveNextNextGaussian = false;
    }1.创建初始值为0的原子long类型的seed;
2.将传入的参数seed重新计算,(seed ^ multiplier) & mask为0x5DEECE642,
  首先我们不必理会multiplier和mask为什么会0x5DEECE66DL和0xffffffffffff,
  multiplier和mask都是常量,可以确认的是相同的seed重新计算后的值也是一样的;
3.设置this.seed的值即刚才重新计算的seed值;
4.将haveNextNextGaussian设置为false,本来默认就是false,
  暂时不用理解haveNextNextGaussian的意义,后面再看看是否有使用到。然后再看看nextInt方法: public int nextInt(int n) {
        if (n <= 0)
            throw new IllegalArgumentException("n must be positive");        if ((n & -n) == n)  // i.e., n is a power of 2
            return (int)((n * (long)next(31)) >> 31);        int bits, val;
        do {
            bits = next(31);
            val = bits % n;
        } while (bits - val + (n-1) < 0);
        return val;
    }

 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));
        return (int)(nextseed >>> (48 - bits));
    }1.如果n不是正整数抛出异常;
2.(n & -n) == n 用来判断n是否为2的x次方,如果是则返回(int)((n * (long)next(31)) >> 31),
   这里有两次使用了next(31),我们就看看next(31)产生了什么整数:
        1).oldseed是(0x2F^0x5DEECE66D)&0xffffffffffff的值0x5DEECE642,
             nextseed为(oldseed*0x5DEECE66D+0xB)& 0xffffffffffff的值0xBA2442955625,
        2).seed.compareAndSet(oldseed, nextseed)判断nextseed是否为预期的结果,
             如果是预期结果返回0xBA2442955625 >>> (48 - 31)为0x5D12214A;
  因此next(31)为0x5D12214A(十进制为1561469258)
 3.  val = bits % n = 0xBA24 % 100 = 58 ,不满足1561469258 - 58 + (100-1) < 0 因此返回val即58
 
以按照以上过程同样也可以推导出为什么第二次是55

解决方案 »

  1.   

    固定的种子,在产生相同范围(题中为0-100)的随机数时,总是产生一组相同的随机数,即第一个是58,第二个是55。
    所谓的随机,是说这一组数是随机的,即在55后面可能出现任意100以内的数字,但第3个确实永远都是那个数字,总而言之,相同种子,出现的是一组固定的集合,但集合中每个位置的的元素是随机的,而出现顺序总是相同的,因为种子相同,它内部得出的结果必然相同
    在Random构造方法中如果是没有参数的构造方法,将会用当前时间来做种子,这样才使得第一个数也是看起来随机的。