Random类实现及局限

public int nextInt (int bound) {
if (bound <= 0)

//（1）根据老种子生成新种子
int r = next(31);
//根据新种子计算随机数
...
return r;
}


• 首先根据老种子生成新种子
• 根据新种子计算新的随机数

protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();			//获得旧的seed
nextseed = (oldseed * multiplier + addend) & mask;		//计算新的seed
} while (!seed.compareAndSet(oldseed, nextseed));			//若seed在此期间没有变仍是oldseed，则更新为新的seed
return (int)(nextseed >>> (48 - bits));
}


Random类中有一个seed变量，首先得到旧的种子，然后计算新的种子，利用compareAndSet()方法将当前种子和oldseed进行比较，如果两者不相等则说明此时seed已经被其他线程更改过，而且方法会返回false，则while()条件为true。继续循环，直到两者相等时方法返回true且while条件为false，中断循环且更新为nextseed。

Random类总结

1. Unsafe机制

	private static final sun.misc.Unsafe UNSAFE;
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> tk = Thread.class;

SEED = UNSAFE.objectFieldOffset

PROBE = UNSAFE.objectFieldOffset

SECONDARY = UNSAFE.objectFieldOffset
} catch (Exception e) {
throw new Error(e);
}
}


	static final ThreadLocalRandom instance = new ThreadLocalRandom();
public static ThreadLocalRandom current() {
localInit();
return instance;
}

static final void localInit() {
int p = probeGenerator.addAndGet(PROBE_INCREMENT);
int probe = (p == 0) ? 1 : p; // skip 0  ，不让PROBE变量为0
long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
UNSAFE.putLong(t, SEED, seed);		//初始化当前线程的threadLocalRandomSeed变量
UNSAFE.putInt(t, PROBE, probe);		//初始化当前线程的threadLocalRandomProbe变量
}


3. int nextInt()方法

	public int nextInt(int bound) {
if (bound <= 0)
int r = mix32(nextSeed());			//根据当前线程中的种子计算新种子
int m = bound - 1;						//根据新种子计算随机数
if ((bound & m) == 0) // power of two
r &= m;
else { // reject over-represented candidates
for (int u = r >>> 1;
u + m - (r = u % bound) < 0;
u = mix32(nextSeed()) >>> 1)
;
}
return r;
}

final long nextSeed() {
Thread t; long r; // read and update per-thread seed

//获取当前线程中的种子，并在其基础上累加GAMMA作为新种子，
r = UNSAFE.getLong(t, SEED) + GAMMA);
return r;
}