newrandom/ThreadLocalRandom.java
author briangoetz
Thu, 23 May 2019 16:45:56 -0400
branchbriangoetz-test-branch
changeset 57369 6d87e9f7a1ec
permissions -rwxr-xr-x
Initial comment in newrandom/
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
57369
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     1
/*
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     2
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     3
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     4
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     5
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     6
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     7
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     8
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
     9
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    10
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    11
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    12
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    13
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    14
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    15
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    16
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    17
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    18
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    19
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    20
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    21
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    22
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    23
 */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    24
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    25
/*
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    26
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    27
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    28
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    29
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    30
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    31
 * Written by Doug Lea with assistance from members of JCP JSR-166
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    32
 * Expert Group and released to the public domain, as explained at
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    33
 * http://creativecommons.org/publicdomain/zero/1.0/
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    34
 */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    35
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    36
// package java.util.concurrent;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    37
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    38
import java.io.ObjectStreamField;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    39
import java.math.BigInteger;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    40
// import java.util.Random;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    41
import java.util.Spliterator;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    42
import java.util.concurrent.atomic.AtomicInteger;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    43
import java.util.concurrent.atomic.AtomicLong;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    44
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    45
/**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    46
 * A random number generator isolated to the current thread.  Like the
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    47
 * global {@link java.util.Random} generator used by the {@link
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    48
 * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    49
 * with an internally generated seed that may not otherwise be
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    50
 * modified. When applicable, use of {@code ThreadLocalRandom} rather
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    51
 * than shared {@code Random} objects in concurrent programs will
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    52
 * typically encounter much less overhead and contention.  Use of
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    53
 * {@code ThreadLocalRandom} is particularly appropriate when multiple
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    54
 * tasks (for example, each a {@link ForkJoinTask}) use random numbers
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    55
 * in parallel in thread pools.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    56
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    57
 * <p>Usages of this class should typically be of the form:
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    58
 * {@code ThreadLocalRandom.current().nextX(...)} (where
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    59
 * {@code X} is {@code Int}, {@code Long}, etc).
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    60
 * When all usages are of this form, it is never possible to
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    61
 * accidently share a {@code ThreadLocalRandom} across multiple threads.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    62
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    63
 * <p>This class also provides additional commonly used bounded random
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    64
 * generation methods.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    65
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    66
 * <p>Instances of {@code ThreadLocalRandom} are not cryptographically
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    67
 * secure.  Consider instead using {@link java.security.SecureRandom}
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    68
 * in security-sensitive applications. Additionally,
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    69
 * default-constructed instances do not use a cryptographically random
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    70
 * seed unless the {@linkplain System#getProperty system property}
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    71
 * {@code java.util.secureRandomSeed} is set to {@code true}.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    72
 *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    73
 * @since 1.7
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    74
 * @author Doug Lea
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    75
 */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    76
public class ThreadLocalRandom extends Random {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    77
    /*
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    78
     * This class implements the java.util.Random API (and subclasses
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    79
     * Random) using a single static instance that accesses random
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    80
     * number state held in class Thread (primarily, field
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    81
     * threadLocalRandomSeed). In doing so, it also provides a home
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    82
     * for managing package-private utilities that rely on exactly the
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    83
     * same state as needed to maintain the ThreadLocalRandom
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    84
     * instances. We leverage the need for an initialization flag
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    85
     * field to also use it as a "probe" -- a self-adjusting thread
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    86
     * hash used for contention avoidance, as well as a secondary
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    87
     * simpler (xorShift) random seed that is conservatively used to
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    88
     * avoid otherwise surprising users by hijacking the
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    89
     * ThreadLocalRandom sequence.  The dual use is a marriage of
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    90
     * convenience, but is a simple and efficient way of reducing
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    91
     * application-level overhead and footprint of most concurrent
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    92
     * programs.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    93
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    94
     * Even though this class subclasses java.util.Random, it uses the
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    95
     * same basic algorithm as java.util.SplittableRandom.  (See its
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    96
     * internal documentation for explanations, which are not repeated
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    97
     * here.)  Because ThreadLocalRandoms are not splittable
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    98
     * though, we use only a single 64bit gamma.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
    99
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   100
     * Because this class is in a different package than class Thread,
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   101
     * field access methods use Unsafe to bypass access control rules.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   102
     * To conform to the requirements of the Random superclass
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   103
     * constructor, the common static ThreadLocalRandom maintains an
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   104
     * "initialized" field for the sake of rejecting user calls to
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   105
     * setSeed while still allowing a call from constructor.  Note
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   106
     * that serialization is completely unnecessary because there is
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   107
     * only a static singleton.  But we generate a serial form
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   108
     * containing "rnd" and "initialized" fields to ensure
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   109
     * compatibility across versions.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   110
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   111
     * Implementations of non-core methods are mostly the same as in
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   112
     * SplittableRandom, that were in part derived from a previous
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   113
     * version of this class.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   114
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   115
     * The nextLocalGaussian ThreadLocal supports the very rarely used
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   116
     * nextGaussian method by providing a holder for the second of a
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   117
     * pair of them. As is true for the base class version of this
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   118
     * method, this time/space tradeoff is probably never worthwhile,
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   119
     * but we provide identical statistical properties.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   120
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   121
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   122
    /** Generates per-thread initialization/probe field */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   123
    private static final AtomicInteger probeGenerator =
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   124
        new AtomicInteger();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   125
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   126
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   127
     * The next seed for default constructors.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   128
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   129
    private static final AtomicLong seeder = new AtomicLong(RngSupport.initialSeed());
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   130
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   131
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   132
     * The seed increment
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   133
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   134
    private static final long GAMMA = 0x9e3779b97f4a7c15L;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   135
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   136
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   137
     * The increment for generating probe values
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   138
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   139
    private static final int PROBE_INCREMENT = 0x9e3779b9;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   140
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   141
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   142
     * The increment of seeder per new instance
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   143
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   144
    private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   145
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   146
    // Constants from SplittableRandom
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   147
    private static final double DOUBLE_UNIT = 0x1.0p-53;  // 1.0  / (1L << 53)
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   148
    private static final float  FLOAT_UNIT  = 0x1.0p-24f; // 1.0f / (1 << 24)
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   149
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   150
    /** Rarely-used holder for the second of a pair of Gaussians */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   151
    private static final ThreadLocal<Double> nextLocalGaussian =
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   152
        new ThreadLocal<Double>();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   153
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   154
    private static long mix64(long z) {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   155
        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   156
        z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   157
        return z ^ (z >>> 33);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   158
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   159
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   160
    private static int mix32(long z) {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   161
        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   162
        return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   163
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   164
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   165
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   166
     * Field used only during singleton initialization.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   167
     * True when constructor completes.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   168
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   169
    boolean initialized;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   170
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   171
    /** Constructor used only for static singleton */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   172
    private ThreadLocalRandom() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   173
        initialized = true; // false during super() call
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   174
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   175
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   176
    /** The common ThreadLocalRandom */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   177
    static final ThreadLocalRandom instance = new ThreadLocalRandom();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   178
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   179
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   180
     * Initialize Thread fields for the current thread.  Called only
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   181
     * when Thread.threadLocalRandomProbe is zero, indicating that a
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   182
     * thread local seed value needs to be generated. Note that even
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   183
     * though the initialization is purely thread-local, we need to
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   184
     * rely on (static) atomic generators to initialize the values.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   185
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   186
    static final void localInit() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   187
        int p = probeGenerator.addAndGet(PROBE_INCREMENT);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   188
        int probe = (p == 0) ? 1 : p; // skip 0
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   189
        long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   190
        Thread t = Thread.currentThread();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   191
        UNSAFE.putLong(t, SEED, seed);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   192
        UNSAFE.putInt(t, PROBE, probe);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   193
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   194
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   195
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   196
     * Returns the current thread's {@code ThreadLocalRandom}.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   197
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   198
     * @return the current thread's {@code ThreadLocalRandom}
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   199
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   200
    public static ThreadLocalRandom current() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   201
        if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   202
            localInit();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   203
        return instance;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   204
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   205
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   206
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   207
     * Throws {@code UnsupportedOperationException}.  Setting seeds in
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   208
     * this generator is not supported.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   209
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   210
     * @throws UnsupportedOperationException always
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   211
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   212
    public void setSeed(long seed) {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   213
        // only allow call from super() constructor
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   214
        if (initialized)
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   215
            throw new UnsupportedOperationException();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   216
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   217
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   218
    final long nextSeed() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   219
        Thread t; long r; // read and update per-thread seed
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   220
        UNSAFE.putLong(t = Thread.currentThread(), SEED,
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   221
                       r = UNSAFE.getLong(t, SEED) + GAMMA);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   222
        return r;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   223
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   224
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   225
    // We must define this (to override the definition inherited from
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   226
    // class Random), but we don't use it from within other methods.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   227
    protected int next(int bits) {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   228
        return (int)(mix64(nextSeed()) >>> (64 - bits));
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   229
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   230
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   231
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   232
     * Returns a pseudorandom {@code int} value.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   233
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   234
     * @return a pseudorandom {@code int} value
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   235
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   236
    public int nextInt() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   237
        return mix32(nextSeed());
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   238
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   239
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   240
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   241
     * Returns a pseudorandom {@code long} value.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   242
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   243
     * @return a pseudorandom {@code long} value
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   244
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   245
    public long nextLong() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   246
        return mix64(nextSeed());
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   247
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   248
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   249
    public double nextGaussian() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   250
        // Use nextLocalGaussian instead of nextGaussian field
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   251
        Double d = nextLocalGaussian.get();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   252
        if (d != null) {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   253
            nextLocalGaussian.set(null);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   254
            return d.doubleValue();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   255
        }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   256
        double v1, v2, s;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   257
        do {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   258
            v1 = 2 * nextDouble() - 1; // between -1 and 1
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   259
            v2 = 2 * nextDouble() - 1; // between -1 and 1
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   260
            s = v1 * v1 + v2 * v2;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   261
        } while (s >= 1 || s == 0);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   262
        double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   263
        nextLocalGaussian.set(new Double(v2 * multiplier));
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   264
        return v1 * multiplier;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   265
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   266
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   267
    static final BigInteger thePeriod = BigInteger.valueOf(1).shiftLeft(64);  // Period is 2**64
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   268
    public BigInteger period() { return thePeriod; }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   269
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   270
    // Within-package utilities
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   271
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   272
    /*
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   273
     * Descriptions of the usages of the methods below can be found in
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   274
     * the classes that use them. Briefly, a thread's "probe" value is
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   275
     * a non-zero hash code that (probably) does not collide with
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   276
     * other existing threads with respect to any power of two
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   277
     * collision space. When it does collide, it is pseudo-randomly
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   278
     * adjusted (using a Marsaglia XorShift). The nextSecondarySeed
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   279
     * method is used in the same contexts as ThreadLocalRandom, but
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   280
     * only for transient usages such as random adaptive spin/block
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   281
     * sequences for which a cheap Rng suffices and for which it could
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   282
     * in principle disrupt user-visible statistical properties of the
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   283
     * main ThreadLocalRandom if we were to use it.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   284
     *
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   285
     * Note: Because of package-protection issues, versions of some
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   286
     * these methods also appear in some subpackage classes.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   287
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   288
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   289
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   290
     * Returns the probe value for the current thread without forcing
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   291
     * initialization. Note that invoking ThreadLocalRandom.current()
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   292
     * can be used to force initialization on zero return.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   293
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   294
    static final int getProbe() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   295
        return UNSAFE.getInt(Thread.currentThread(), PROBE);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   296
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   297
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   298
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   299
     * Pseudo-randomly advances and records the given probe value for the
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   300
     * given thread.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   301
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   302
    static final int advanceProbe(int probe) {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   303
        probe ^= probe << 13;   // xorshift
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   304
        probe ^= probe >>> 17;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   305
        probe ^= probe << 5;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   306
        UNSAFE.putInt(Thread.currentThread(), PROBE, probe);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   307
        return probe;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   308
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   309
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   310
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   311
     * Returns the pseudo-randomly initialized or updated secondary seed.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   312
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   313
    static final int nextSecondarySeed() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   314
        int r;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   315
        Thread t = Thread.currentThread();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   316
        if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   317
            r ^= r << 13;   // xorshift
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   318
            r ^= r >>> 17;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   319
            r ^= r << 5;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   320
        }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   321
        else {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   322
            localInit();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   323
            if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   324
                r = 1; // avoid zero
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   325
        }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   326
        UNSAFE.putInt(t, SECONDARY, r);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   327
        return r;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   328
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   329
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   330
    // Serialization support
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   331
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   332
    private static final long serialVersionUID = -5851777807851030925L;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   333
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   334
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   335
     * @serialField rnd long
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   336
     *              seed for random computations
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   337
     * @serialField initialized boolean
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   338
     *              always true
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   339
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   340
    private static final ObjectStreamField[] serialPersistentFields = {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   341
            new ObjectStreamField("rnd", long.class),
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   342
            new ObjectStreamField("initialized", boolean.class),
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   343
    };
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   344
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   345
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   346
     * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   347
     * @param s the stream
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   348
     * @throws java.io.IOException if an I/O error occurs
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   349
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   350
    private void writeObject(java.io.ObjectOutputStream s)
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   351
        throws java.io.IOException {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   352
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   353
        java.io.ObjectOutputStream.PutField fields = s.putFields();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   354
        fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   355
        fields.put("initialized", true);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   356
        s.writeFields();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   357
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   358
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   359
    /**
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   360
     * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   361
     * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   362
     */
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   363
    private Object readResolve() {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   364
        return current();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   365
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   366
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   367
    // Unsafe mechanics
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   368
    private static final sun.misc.Unsafe UNSAFE;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   369
    private static final long SEED;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   370
    private static final long PROBE;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   371
    private static final long SECONDARY;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   372
    static {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   373
        try {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   374
            UNSAFE = sun.misc.Unsafe.getUnsafe();
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   375
            Class<?> tk = Thread.class;
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   376
            SEED = UNSAFE.objectFieldOffset
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   377
                (tk.getDeclaredField("threadLocalRandomSeed"));
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   378
            PROBE = UNSAFE.objectFieldOffset
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   379
                (tk.getDeclaredField("threadLocalRandomProbe"));
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   380
            SECONDARY = UNSAFE.objectFieldOffset
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   381
                (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   382
        } catch (Exception e) {
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   383
            throw new Error(e);
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   384
        }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   385
    }
6d87e9f7a1ec Initial comment in newrandom/
briangoetz
parents:
diff changeset
   386
}