src/share/classes/java/util/concurrent/ThreadLocalRandom.java
Print this page
*** 132,184 ****
new AtomicInteger();
/**
* The next seed for default constructors.
*/
! private static final AtomicLong seeder = new AtomicLong(initialSeed());
!
! private static long initialSeed() {
! String pp = java.security.AccessController.doPrivileged(
! new sun.security.action.GetPropertyAction(
! "java.util.secureRandomSeed"));
! if (pp != null && pp.equalsIgnoreCase("true")) {
! byte[] seedBytes = java.security.SecureRandom.getSeed(8);
! long s = (long)(seedBytes[0]) & 0xffL;
! for (int i = 1; i < 8; ++i)
! s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
! return s;
! }
! long h = 0L;
! try {
! Enumeration<NetworkInterface> ifcs =
! NetworkInterface.getNetworkInterfaces();
! boolean retry = false; // retry once if getHardwareAddress is null
! while (ifcs.hasMoreElements()) {
! NetworkInterface ifc = ifcs.nextElement();
! if (!ifc.isVirtual()) { // skip fake addresses
! byte[] bs = ifc.getHardwareAddress();
! if (bs != null) {
! int n = bs.length;
! int m = Math.min(n >>> 1, 4);
! for (int i = 0; i < m; ++i)
! h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i];
! if (m < 4)
! h = (h << 8) ^ bs[n-1-m];
! h = mix64(h);
! break;
! }
! else if (!retry)
! retry = true;
! else
! break;
! }
! }
! } catch (Exception ignore) {
! }
! return (h ^ mix64(System.currentTimeMillis()) ^
mix64(System.nanoTime()));
- }
/**
* The seed increment
*/
private static final long GAMMA = 0x9e3779b97f4a7c15L;
--- 132,145 ----
new AtomicInteger();
/**
* The next seed for default constructors.
*/
! private static final AtomicLong seeder =
! // this is just intermediate value - see static block at end of file...
! new AtomicLong(mix64(System.currentTimeMillis()) ^
mix64(System.nanoTime()));
/**
* The seed increment
*/
private static final long GAMMA = 0x9e3779b97f4a7c15L;
*** 1077,1087 ****
*/
private Object readResolve() {
return current();
}
! // Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;
static {
--- 1038,1048 ----
*/
private Object readResolve() {
return current();
}
! // Unsafe mechanics and "seeder" initialization
private static final sun.misc.Unsafe UNSAFE;
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;
static {
*** 1095,1101 ****
--- 1056,1107 ----
SECONDARY = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSecondarySeed"));
} catch (Exception e) {
throw new Error(e);
}
+
+ // finish initialization of "seeder"
+ String pp = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "java.util.secureRandomSeed"));
+ if (pp != null && pp.equalsIgnoreCase("true")) {
+ byte[] seedBytes = java.security.SecureRandom.getSeed(8);
+ long s = (long)(seedBytes[0]) & 0xffL;
+ for (int i = 1; i < 8; ++i)
+ s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+ seeder.set(s);
+ } else {
+ try {
+ long h = 0L;
+ Enumeration<NetworkInterface> ifcs =
+ NetworkInterface.getNetworkInterfaces();
+ boolean retry = false; // retry once if getHardwareAddress is null
+ while (ifcs.hasMoreElements()) {
+ NetworkInterface ifc = ifcs.nextElement();
+ if (!ifc.isVirtual()) { // skip fake addresses
+ byte[] bs = ifc.getHardwareAddress();
+ if (bs != null) {
+ int n = bs.length;
+ int m = Math.min(n >>> 1, 4);
+ for (int i = 0; i < m; ++i)
+ h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i];
+ if (m < 4)
+ h = (h << 8) ^ bs[n-1-m];
+ h = mix64(h);
+ break;
}
+ else if (!retry)
+ retry = true;
+ else
+ break;
+ }
+ }
+ seeder.set(seeder.get() ^ h);
+ } catch (Exception ignore) {
+ }
+ }
+ // trigger re-initialization of thread-local state
+ // in case TLR has already been used in current thread
+ UNSAFE.putInt(Thread.currentThread(), PROBE, 0);
+ }
+
}