ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.18
Committed: Fri Jul 19 19:34:43 2013 UTC (10 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.17: +1 -1 lines
Log Message:
enforce standard javadoc tag order

File Contents

# User Rev Content
1 jsr166 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.6 * http://creativecommons.org/publicdomain/zero/1.0/
5 jsr166 1.1 */
6    
7     package java.util.concurrent;
8    
9 dl 1.9 import java.io.ObjectStreamField;
10 jsr166 1.1 import java.util.Random;
11 dl 1.7 import java.util.concurrent.atomic.AtomicInteger;
12     import java.util.concurrent.atomic.AtomicLong;
13 jsr166 1.1
14     /**
15 jsr166 1.3 * A random number generator isolated to the current thread. Like the
16 jsr166 1.2 * global {@link java.util.Random} generator used by the {@link
17 jsr166 1.3 * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
18     * with an internally generated seed that may not otherwise be
19     * modified. When applicable, use of {@code ThreadLocalRandom} rather
20     * than shared {@code Random} objects in concurrent programs will
21     * typically encounter much less overhead and contention. Use of
22     * {@code ThreadLocalRandom} is particularly appropriate when multiple
23     * tasks (for example, each a {@link ForkJoinTask}) use random numbers
24     * in parallel in thread pools.
25 jsr166 1.1 *
26     * <p>Usages of this class should typically be of the form:
27     * {@code ThreadLocalRandom.current().nextX(...)} (where
28     * {@code X} is {@code Int}, {@code Long}, etc).
29     * When all usages are of this form, it is never possible to
30 jsr166 1.3 * accidently share a {@code ThreadLocalRandom} across multiple threads.
31 jsr166 1.1 *
32     * <p>This class also provides additional commonly used bounded random
33     * generation methods.
34     *
35     * @since 1.7
36     * @author Doug Lea
37     */
38     public class ThreadLocalRandom extends Random {
39 dl 1.7 /*
40     * This class implements the java.util.Random API (and subclasses
41     * Random) using a single static instance that accesses random
42     * number state held in class Thread (primarily, field
43     * threadLocalRandomSeed). In doing so, it also provides a home
44     * for managing package-private utilities that rely on exactly the
45     * same state as needed to maintain the ThreadLocalRandom
46     * instances. We leverage the need for an initialization flag
47     * field to also use it as a "probe" -- a self-adjusting thread
48     * hash used for contention avoidance, as well as a secondary
49     * simpler (xorShift) random seed that is conservatively used to
50     * avoid otherwise surprising users by hijacking the
51     * ThreadLocalRandom sequence. The dual use is a marriage of
52     * convenience, but is a simple and efficient way of reducing
53     * application-level overhead and footprint of most concurrent
54     * programs.
55     *
56     * Because this class is in a different package than class Thread,
57 jsr166 1.15 * field access methods use Unsafe to bypass access control rules.
58     * The base functionality of Random methods is conveniently
59     * isolated in method next(bits), that just reads and writes the
60     * Thread field rather than its own field. However, to conform to
61     * the requirements of the Random superclass constructor, the
62     * common static ThreadLocalRandom maintains an "initialized"
63     * field for the sake of rejecting user calls to setSeed while
64     * still allowing a call from constructor. Note that
65     * serialization is completely unnecessary because there is only a
66     * static singleton. But we generate a serial form containing
67     * "rnd" and "initialized" fields to ensure compatibility across
68     * versions.
69 dl 1.7 *
70 jsr166 1.15 * Per-thread initialization is similar to that in the no-arg
71 dl 1.7 * Random constructor, but we avoid correlation among not only
72     * initial seeds of those created in different threads, but also
73     * those created using class Random itself; while at the same time
74     * not changing any statistical properties. So we use the same
75     * underlying multiplicative sequence, but start the sequence far
76     * away from the base version, and then merge (xor) current time
77     * and per-thread probe bits to generate initial values.
78     *
79     * The nextLocalGaussian ThreadLocal supports the very rarely used
80     * nextGaussian method by providing a holder for the second of a
81     * pair of them. As is true for the base class version of this
82     * method, this time/space tradeoff is probably never worthwhile,
83     * but we provide identical statistical properties.
84     */
85    
86 jsr166 1.1 // same constants as Random, but must be redeclared because private
87 jsr166 1.5 private static final long multiplier = 0x5DEECE66DL;
88     private static final long addend = 0xBL;
89     private static final long mask = (1L << 48) - 1;
90 dl 1.7 private static final int PROBE_INCREMENT = 0x61c88647;
91 jsr166 1.1
92 dl 1.7 /** Generates the basis for per-thread initial seed values */
93     private static final AtomicLong seedGenerator =
94     new AtomicLong(1269533684904616924L);
95 jsr166 1.1
96 dl 1.7 /** Generates per-thread initialization/probe field */
97     private static final AtomicInteger probeGenerator =
98     new AtomicInteger(0xe80f8647);
99 jsr166 1.1
100 dl 1.7 /** Rarely-used holder for the second of a pair of Gaussians */
101     private static final ThreadLocal<Double> nextLocalGaussian =
102     new ThreadLocal<Double>();
103 jsr166 1.1
104 jsr166 1.11 /**
105     * Field used only during singleton initialization.
106     * True when constructor completes.
107 jsr166 1.1 */
108 jsr166 1.11 boolean initialized;
109 dl 1.7
110     /** Constructor used only for static singleton */
111     private ThreadLocalRandom() {
112     initialized = true; // false during super() call
113     }
114 jsr166 1.1
115 dl 1.7 /** The common ThreadLocalRandom */
116     static final ThreadLocalRandom instance = new ThreadLocalRandom();
117 jsr166 1.1
118     /**
119 dl 1.7 * Initialize Thread fields for the current thread. Called only
120     * when Thread.threadLocalRandomProbe is zero, indicating that a
121     * thread local seed value needs to be generated. Note that even
122     * though the initialization is purely thread-local, we need to
123     * rely on (static) atomic generators to initialize the values.
124     */
125     static final void localInit() {
126     int p = probeGenerator.getAndAdd(PROBE_INCREMENT);
127     int probe = (p == 0) ? 1 : p; // skip 0
128     long current, next;
129     do { // same sequence as j.u.Random but different initial value
130     current = seedGenerator.get();
131     next = current * 181783497276652981L;
132     } while (!seedGenerator.compareAndSet(current, next));
133     long r = next ^ ((long)probe << 32) ^ System.nanoTime();
134     Thread t = Thread.currentThread();
135     UNSAFE.putLong(t, SEED, r);
136     UNSAFE.putInt(t, PROBE, probe);
137 jsr166 1.1 }
138    
139     /**
140 jsr166 1.3 * Returns the current thread's {@code ThreadLocalRandom}.
141 jsr166 1.1 *
142 jsr166 1.3 * @return the current thread's {@code ThreadLocalRandom}
143 jsr166 1.1 */
144     public static ThreadLocalRandom current() {
145 dl 1.7 if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
146     localInit();
147     return instance;
148 jsr166 1.1 }
149    
150     /**
151 jsr166 1.3 * Throws {@code UnsupportedOperationException}. Setting seeds in
152     * this generator is not supported.
153 jsr166 1.1 *
154     * @throws UnsupportedOperationException always
155     */
156     public void setSeed(long seed) {
157 jsr166 1.15 // only allow call from super() constructor
158     if (initialized)
159 jsr166 1.1 throw new UnsupportedOperationException();
160     }
161    
162     protected int next(int bits) {
163 dl 1.7 Thread t; long r; // read and update per-thread seed
164     UNSAFE.putLong
165     (t = Thread.currentThread(), SEED,
166     r = (UNSAFE.getLong(t, SEED) * multiplier + addend) & mask);
167     return (int) (r >>> (48-bits));
168 jsr166 1.1 }
169    
170     /**
171     * Returns a pseudorandom, uniformly distributed value between the
172     * given least value (inclusive) and bound (exclusive).
173     *
174     * @param least the least value returned
175     * @param bound the upper bound (exclusive)
176 jsr166 1.18 * @return the next value
177 jsr166 1.1 * @throws IllegalArgumentException if least greater than or equal
178     * to bound
179     */
180     public int nextInt(int least, int bound) {
181     if (least >= bound)
182     throw new IllegalArgumentException();
183     return nextInt(bound - least) + least;
184     }
185    
186     /**
187     * Returns a pseudorandom, uniformly distributed value
188     * between 0 (inclusive) and the specified value (exclusive).
189     *
190     * @param n the bound on the random number to be returned. Must be
191     * positive.
192     * @return the next value
193     * @throws IllegalArgumentException if n is not positive
194     */
195     public long nextLong(long n) {
196     if (n <= 0)
197     throw new IllegalArgumentException("n must be positive");
198     // Divide n by two until small enough for nextInt. On each
199     // iteration (at most 31 of them but usually much less),
200     // randomly choose both whether to include high bit in result
201     // (offset) and whether to continue with the lower vs upper
202     // half (which makes a difference only if odd).
203     long offset = 0;
204     while (n >= Integer.MAX_VALUE) {
205     int bits = next(2);
206     long half = n >>> 1;
207     long nextn = ((bits & 2) == 0) ? half : n - half;
208     if ((bits & 1) == 0)
209     offset += n - nextn;
210     n = nextn;
211     }
212     return offset + nextInt((int) n);
213     }
214    
215     /**
216     * Returns a pseudorandom, uniformly distributed value between the
217     * given least value (inclusive) and bound (exclusive).
218     *
219     * @param least the least value returned
220     * @param bound the upper bound (exclusive)
221     * @return the next value
222     * @throws IllegalArgumentException if least greater than or equal
223     * to bound
224     */
225     public long nextLong(long least, long bound) {
226     if (least >= bound)
227     throw new IllegalArgumentException();
228     return nextLong(bound - least) + least;
229     }
230    
231     /**
232     * Returns a pseudorandom, uniformly distributed {@code double} value
233     * between 0 (inclusive) and the specified value (exclusive).
234     *
235     * @param n the bound on the random number to be returned. Must be
236     * positive.
237     * @return the next value
238     * @throws IllegalArgumentException if n is not positive
239     */
240     public double nextDouble(double n) {
241     if (n <= 0)
242     throw new IllegalArgumentException("n must be positive");
243     return nextDouble() * n;
244     }
245    
246     /**
247     * Returns a pseudorandom, uniformly distributed value between the
248     * given least value (inclusive) and bound (exclusive).
249     *
250     * @param least the least value returned
251     * @param bound the upper bound (exclusive)
252     * @return the next value
253     * @throws IllegalArgumentException if least greater than or equal
254     * to bound
255     */
256     public double nextDouble(double least, double bound) {
257     if (least >= bound)
258     throw new IllegalArgumentException();
259     return nextDouble() * (bound - least) + least;
260     }
261    
262 dl 1.7 public double nextGaussian() {
263     // Use nextLocalGaussian instead of nextGaussian field
264     Double d = nextLocalGaussian.get();
265     if (d != null) {
266     nextLocalGaussian.set(null);
267     return d.doubleValue();
268     }
269     double v1, v2, s;
270     do {
271     v1 = 2 * nextDouble() - 1; // between -1 and 1
272     v2 = 2 * nextDouble() - 1; // between -1 and 1
273     s = v1 * v1 + v2 * v2;
274     } while (s >= 1 || s == 0);
275     double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
276     nextLocalGaussian.set(new Double(v2 * multiplier));
277     return v1 * multiplier;
278     }
279    
280     // Within-package utilities
281    
282     /*
283     * Descriptions of the usages of the methods below can be found in
284     * the classes that use them. Briefly, a thread's "probe" value is
285     * a non-zero hash code that (probably) does not collide with
286     * other existing threads with respect to any power of two
287     * collision space. When it does collide, it is pseudo-randomly
288     * adjusted (using a Marsaglia XorShift). The nextSecondarySeed
289     * method is used in the same contexts as ThreadLocalRandom, but
290     * only for transient usages such as random adaptive spin/block
291     * sequences for which a cheap RNG suffices and for which it could
292     * in principle disrupt user-visible statistical properties of the
293     * main ThreadLocalRandom if we were to use it.
294     *
295     * Note: Because of package-protection issues, versions of some
296 dl 1.9 * these methods also appear in some subpackage classes.
297 dl 1.7 */
298    
299     /**
300     * Returns the probe value for the current thread without forcing
301     * initialization. Note that invoking ThreadLocalRandom.current()
302     * can be used to force initialization on zero return.
303     */
304     static final int getProbe() {
305     return UNSAFE.getInt(Thread.currentThread(), PROBE);
306     }
307    
308     /**
309     * Pseudo-randomly advances and records the given probe value for the
310     * given thread.
311     */
312     static final int advanceProbe(int probe) {
313     probe ^= probe << 13; // xorshift
314     probe ^= probe >>> 17;
315     probe ^= probe << 5;
316     UNSAFE.putInt(Thread.currentThread(), PROBE, probe);
317     return probe;
318     }
319    
320     /**
321     * Returns the pseudo-randomly initialized or updated secondary seed.
322     */
323     static final int nextSecondarySeed() {
324     int r;
325     Thread t = Thread.currentThread();
326     if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
327     r ^= r << 13; // xorshift
328     r ^= r >>> 17;
329     r ^= r << 5;
330     }
331 dl 1.10 else {
332     localInit();
333     if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
334     r = 1; // avoid zero
335     }
336 dl 1.7 UNSAFE.putInt(t, SECONDARY, r);
337     return r;
338     }
339    
340 jsr166 1.13 // Serialization support
341 dl 1.9
342 jsr166 1.1 private static final long serialVersionUID = -5851777807851030925L;
343 dl 1.7
344 dl 1.9 /**
345 jsr166 1.14 * @serialField rnd long
346     * seed for random computations
347     * @serialField initialized boolean
348     * always true
349     */
350     private static final ObjectStreamField[] serialPersistentFields = {
351     new ObjectStreamField("rnd", long.class),
352     new ObjectStreamField("initialized", boolean.class),
353     };
354    
355     /**
356     * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
357 jsr166 1.16 * @param s the stream
358 jsr166 1.17 * @throws java.io.IOException if an I/O error occurs
359 jsr166 1.14 */
360 jsr166 1.16 private void writeObject(java.io.ObjectOutputStream s)
361 jsr166 1.14 throws java.io.IOException {
362    
363 jsr166 1.16 java.io.ObjectOutputStream.PutField fields = s.putFields();
364 jsr166 1.14 fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
365     fields.put("initialized", true);
366 jsr166 1.16 s.writeFields();
367 jsr166 1.14 }
368    
369     /**
370 dl 1.9 * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
371 jsr166 1.16 * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
372 dl 1.9 */
373     private Object readResolve() {
374     return current();
375     }
376    
377 dl 1.7 // Unsafe mechanics
378     private static final sun.misc.Unsafe UNSAFE;
379     private static final long SEED;
380     private static final long PROBE;
381     private static final long SECONDARY;
382     static {
383     try {
384     UNSAFE = sun.misc.Unsafe.getUnsafe();
385     Class<?> tk = Thread.class;
386     SEED = UNSAFE.objectFieldOffset
387     (tk.getDeclaredField("threadLocalRandomSeed"));
388     PROBE = UNSAFE.objectFieldOffset
389     (tk.getDeclaredField("threadLocalRandomProbe"));
390     SECONDARY = UNSAFE.objectFieldOffset
391     (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
392     } catch (Exception e) {
393     throw new Error(e);
394     }
395     }
396 jsr166 1.1 }