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); + } + }