180 |
|
int probe = (p == 0) ? 1 : p; // skip 0 |
181 |
|
long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT)); |
182 |
|
Thread t = Thread.currentThread(); |
183 |
< |
UNSAFE.putLong(t, SEED, seed); |
184 |
< |
UNSAFE.putInt(t, PROBE, probe); |
183 |
> |
U.putLong(t, SEED, seed); |
184 |
> |
U.putInt(t, PROBE, probe); |
185 |
|
} |
186 |
|
|
187 |
|
/** |
190 |
|
* @return the current thread's {@code ThreadLocalRandom} |
191 |
|
*/ |
192 |
|
public static ThreadLocalRandom current() { |
193 |
< |
if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0) |
193 |
> |
if (U.getInt(Thread.currentThread(), PROBE) == 0) |
194 |
|
localInit(); |
195 |
|
return instance; |
196 |
|
} |
209 |
|
|
210 |
|
final long nextSeed() { |
211 |
|
Thread t; long r; // read and update per-thread seed |
212 |
< |
UNSAFE.putLong(t = Thread.currentThread(), SEED, |
213 |
< |
r = UNSAFE.getLong(t, SEED) + GAMMA); |
212 |
> |
U.putLong(t = Thread.currentThread(), SEED, |
213 |
> |
r = U.getLong(t, SEED) + GAMMA); |
214 |
|
return r; |
215 |
|
} |
216 |
|
|
949 |
|
* can be used to force initialization on zero return. |
950 |
|
*/ |
951 |
|
static final int getProbe() { |
952 |
< |
return UNSAFE.getInt(Thread.currentThread(), PROBE); |
952 |
> |
return U.getInt(Thread.currentThread(), PROBE); |
953 |
|
} |
954 |
|
|
955 |
|
/** |
960 |
|
probe ^= probe << 13; // xorshift |
961 |
|
probe ^= probe >>> 17; |
962 |
|
probe ^= probe << 5; |
963 |
< |
UNSAFE.putInt(Thread.currentThread(), PROBE, probe); |
963 |
> |
U.putInt(Thread.currentThread(), PROBE, probe); |
964 |
|
return probe; |
965 |
|
} |
966 |
|
|
970 |
|
static final int nextSecondarySeed() { |
971 |
|
int r; |
972 |
|
Thread t = Thread.currentThread(); |
973 |
< |
if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) { |
973 |
> |
if ((r = U.getInt(t, SECONDARY)) != 0) { |
974 |
|
r ^= r << 13; // xorshift |
975 |
|
r ^= r >>> 17; |
976 |
|
r ^= r << 5; |
977 |
|
} |
978 |
|
else if ((r = mix32(seeder.getAndAdd(SEEDER_INCREMENT))) == 0) |
979 |
|
r = 1; // avoid zero |
980 |
< |
UNSAFE.putInt(t, SECONDARY, r); |
980 |
> |
U.putInt(t, SECONDARY, r); |
981 |
|
return r; |
982 |
|
} |
983 |
|
|
1005 |
|
throws java.io.IOException { |
1006 |
|
|
1007 |
|
java.io.ObjectOutputStream.PutField fields = s.putFields(); |
1008 |
< |
fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED)); |
1008 |
> |
fields.put("rnd", U.getLong(Thread.currentThread(), SEED)); |
1009 |
|
fields.put("initialized", true); |
1010 |
|
s.writeFields(); |
1011 |
|
} |
1019 |
|
} |
1020 |
|
|
1021 |
|
// Unsafe mechanics |
1022 |
< |
private static final sun.misc.Unsafe UNSAFE; |
1022 |
> |
private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); |
1023 |
|
private static final long SEED; |
1024 |
|
private static final long PROBE; |
1025 |
|
private static final long SECONDARY; |
1026 |
|
static { |
1027 |
|
try { |
1028 |
< |
UNSAFE = sun.misc.Unsafe.getUnsafe(); |
1029 |
< |
Class<?> tk = Thread.class; |
1030 |
< |
SEED = UNSAFE.objectFieldOffset |
1031 |
< |
(tk.getDeclaredField("threadLocalRandomSeed")); |
1032 |
< |
PROBE = UNSAFE.objectFieldOffset |
1033 |
< |
(tk.getDeclaredField("threadLocalRandomProbe")); |
1034 |
< |
SECONDARY = UNSAFE.objectFieldOffset |
1035 |
< |
(tk.getDeclaredField("threadLocalRandomSecondarySeed")); |
1028 |
> |
SEED = U.objectFieldOffset |
1029 |
> |
(Thread.class.getDeclaredField("threadLocalRandomSeed")); |
1030 |
> |
PROBE = U.objectFieldOffset |
1031 |
> |
(Thread.class.getDeclaredField("threadLocalRandomProbe")); |
1032 |
> |
SECONDARY = U.objectFieldOffset |
1033 |
> |
(Thread.class.getDeclaredField("threadLocalRandomSecondarySeed")); |
1034 |
|
} catch (ReflectiveOperationException e) { |
1035 |
|
throw new Error(e); |
1036 |
|
} |