看源代码:
public static ThreadLocalRandom current() {
//如果线程第一次调用 current() 方法,执行 localInit()方法
if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
localInit();
return instance;
}
localInit方法:
static final void localInit() {
int p = probeGenerator.addAndGet(PROBE_INCREMENT);
int probe = (p == 0) ? 1 : p; // skip 0
long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
Thread t = Thread.currentThread();
UNSAFE.putLong(t, SEED, seed);
UNSAFE.putInt(t, PROBE, probe);
}
生成随机数时:
public int nextInt(int bound) {
if (bound <= 0)
throw new IllegalArgumentException(BadBound);
//第一处
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
UNSAFE.putLong(t = Thread.currentThread(), SEED,
r = UNSAFE.getLong(t, SEED) + GAMMA);
return r;
}
在主线程调用了 TreadLocalRandom 的 current() 方法,把主线程和主线程的 seed 存入了 UNSAFE。非主线程和 seed 的键值对之前并没有存入 UNSAFE。
所以直接ThreadLocalRandom.current().nextInt()去用。current()方法不会产生多个实例,放心用。