src/share/classes/java/util/concurrent/ThreadLocalRandom.java

Print this page




  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * This file is available under and governed by the GNU General Public
  27  * License version 2 only, as published by the Free Software Foundation.
  28  * However, the following notice accompanied the original version of this
  29  * file:
  30  *
  31  * Written by Doug Lea with assistance from members of JCP JSR-166
  32  * Expert Group and released to the public domain, as explained at
  33  * http://creativecommons.org/publicdomain/zero/1.0/
  34  */
  35 
  36 package java.util.concurrent;
  37 
  38 import java.io.ObjectStreamField;
  39 import java.net.NetworkInterface;
  40 import java.util.Enumeration;
  41 import java.util.Random;
  42 import java.util.Spliterator;
  43 import java.util.concurrent.atomic.AtomicInteger;
  44 import java.util.concurrent.atomic.AtomicLong;
  45 import java.util.function.DoubleConsumer;
  46 import java.util.function.IntConsumer;
  47 import java.util.function.LongConsumer;
  48 import java.util.stream.DoubleStream;
  49 import java.util.stream.IntStream;
  50 import java.util.stream.LongStream;
  51 import java.util.stream.StreamSupport;
  52 
  53 /**
  54  * A random number generator isolated to the current thread.  Like the
  55  * global {@link java.util.Random} generator used by the {@link
  56  * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
  57  * with an internally generated seed that may not otherwise be
  58  * modified. When applicable, use of {@code ThreadLocalRandom} rather
  59  * than shared {@code Random} objects in concurrent programs will
  60  * typically encounter much less overhead and contention.  Use of


 120      * SplittableRandom, that were in part derived from a previous
 121      * version of this class.
 122      *
 123      * The nextLocalGaussian ThreadLocal supports the very rarely used
 124      * nextGaussian method by providing a holder for the second of a
 125      * pair of them. As is true for the base class version of this
 126      * method, this time/space tradeoff is probably never worthwhile,
 127      * but we provide identical statistical properties.
 128      */
 129 
 130     /** Generates per-thread initialization/probe field */
 131     private static final AtomicInteger probeGenerator =
 132         new AtomicInteger();
 133 
 134     /**
 135      * The next seed for default constructors.
 136      */
 137     private static final AtomicLong seeder = new AtomicLong(initialSeed());
 138 
 139     private static long initialSeed() {
 140         String pp = java.security.AccessController.doPrivileged(
 141                 new sun.security.action.GetPropertyAction(
 142                         "java.util.secureRandomSeed"));
 143         if (pp != null && pp.equalsIgnoreCase("true")) {
 144             byte[] seedBytes = java.security.SecureRandom.getSeed(8);
 145             long s = (long)(seedBytes[0]) & 0xffL;
 146             for (int i = 1; i < 8; ++i)
 147                 s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
 148             return s;

 149         }
 150         long h = 0L;
 151         try {
 152             Enumeration<NetworkInterface> ifcs =
 153                     NetworkInterface.getNetworkInterfaces();
 154             boolean retry = false; // retry once if getHardwareAddress is null
 155             while (ifcs.hasMoreElements()) {
 156                 NetworkInterface ifc = ifcs.nextElement();
 157                 if (!ifc.isVirtual()) { // skip fake addresses
 158                     byte[] bs = ifc.getHardwareAddress();
 159                     if (bs != null) {
 160                         int n = bs.length;
 161                         int m = Math.min(n >>> 1, 4);
 162                         for (int i = 0; i < m; ++i)
 163                             h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i];
 164                         if (m < 4)
 165                             h = (h << 8) ^ bs[n-1-m];
 166                         h = mix64(h);
 167                         break;
 168                     }
 169                     else if (!retry)
 170                         retry = true;
 171                     else
 172                         break;
 173                 }
 174             }
 175         } catch (Exception ignore) {
 176         }
 177         return (h ^ mix64(System.currentTimeMillis()) ^
 178                 mix64(System.nanoTime()));
 179     }
 180 
 181     /**
 182      * The seed increment
 183      */
 184     private static final long GAMMA = 0x9e3779b97f4a7c15L;
 185 
 186     /**
 187      * The increment for generating probe values
 188      */
 189     private static final int PROBE_INCREMENT = 0x9e3779b9;
 190 
 191     /**
 192      * The increment of seeder per new instance
 193      */
 194     private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
 195 
 196     // Constants from SplittableRandom
 197     private static final double DOUBLE_UNIT = 0x1.0p-53;  // 1.0  / (1L << 53)
 198     private static final float  FLOAT_UNIT  = 0x1.0p-24f; // 1.0f / (1 << 24)




  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * This file is available under and governed by the GNU General Public
  27  * License version 2 only, as published by the Free Software Foundation.
  28  * However, the following notice accompanied the original version of this
  29  * file:
  30  *
  31  * Written by Doug Lea with assistance from members of JCP JSR-166
  32  * Expert Group and released to the public domain, as explained at
  33  * http://creativecommons.org/publicdomain/zero/1.0/
  34  */
  35 
  36 package java.util.concurrent;
  37 
  38 import java.io.ObjectStreamField;
  39 import sun.security.provider.SeedGenerator;

  40 import java.util.Random;
  41 import java.util.Spliterator;
  42 import java.util.concurrent.atomic.AtomicInteger;
  43 import java.util.concurrent.atomic.AtomicLong;
  44 import java.util.function.DoubleConsumer;
  45 import java.util.function.IntConsumer;
  46 import java.util.function.LongConsumer;
  47 import java.util.stream.DoubleStream;
  48 import java.util.stream.IntStream;
  49 import java.util.stream.LongStream;
  50 import java.util.stream.StreamSupport;
  51 
  52 /**
  53  * A random number generator isolated to the current thread.  Like the
  54  * global {@link java.util.Random} generator used by the {@link
  55  * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
  56  * with an internally generated seed that may not otherwise be
  57  * modified. When applicable, use of {@code ThreadLocalRandom} rather
  58  * than shared {@code Random} objects in concurrent programs will
  59  * typically encounter much less overhead and contention.  Use of


 119      * SplittableRandom, that were in part derived from a previous
 120      * version of this class.
 121      *
 122      * The nextLocalGaussian ThreadLocal supports the very rarely used
 123      * nextGaussian method by providing a holder for the second of a
 124      * pair of them. As is true for the base class version of this
 125      * method, this time/space tradeoff is probably never worthwhile,
 126      * but we provide identical statistical properties.
 127      */
 128 
 129     /** Generates per-thread initialization/probe field */
 130     private static final AtomicInteger probeGenerator =
 131         new AtomicInteger();
 132 
 133     /**
 134      * The next seed for default constructors.
 135      */
 136     private static final AtomicLong seeder = new AtomicLong(initialSeed());
 137 
 138     private static long initialSeed() {
 139         try (SeedGenerator sg = SeedGenerator.getNativeInstance()) {
 140             byte[] seedBytes = new byte[8];
 141             sg.getSeedBytes(seedBytes);


 142             long s = (long)(seedBytes[0]) & 0xffL;
 143             for (int i = 1; i < 8; ++i)
 144                 s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
 145             return s ^ mix64(System.currentTimeMillis()) ^
 146                    mix64(System.nanoTime());
 147         }





























 148     }
 149 
 150     /**
 151      * The seed increment
 152      */
 153     private static final long GAMMA = 0x9e3779b97f4a7c15L;
 154 
 155     /**
 156      * The increment for generating probe values
 157      */
 158     private static final int PROBE_INCREMENT = 0x9e3779b9;
 159 
 160     /**
 161      * The increment of seeder per new instance
 162      */
 163     private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
 164 
 165     // Constants from SplittableRandom
 166     private static final double DOUBLE_UNIT = 0x1.0p-53;  // 1.0  / (1L << 53)
 167     private static final float  FLOAT_UNIT  = 0x1.0p-24f; // 1.0f / (1 << 24)