ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.11
Committed: Mon Jan 28 17:42:42 2013 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.10: +4 -3 lines
Log Message:
convert to javadoc comment

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     * field access methods must use Unsafe to bypass access control
58     * rules. The base functionality of Random methods is
59     * conveniently isolated in method next(bits), that just reads and
60     * writes the Thread field rather than its own field. However, to
61     * conform to the requirements of the Random constructor, during
62     * construction, the common static ThreadLocalRandom must maintain
63     * initialization and value fields, mainly for the sake of
64     * disabling user calls to setSeed while still allowing a call
65     * from constructor. For serialization compatibility, these
66     * fields are left with the same declarations as used in the
67     * previous ThreadLocal-based version of this class, that used
68     * them differently. Note that serialization is completely
69     * unnecessary because there is only a static singleton. But these
70     * mechanics still ensure compatibility across versions.
71     *
72     * Per-instance initialization is similar to that in the no-arg
73     * Random constructor, but we avoid correlation among not only
74     * initial seeds of those created in different threads, but also
75     * those created using class Random itself; while at the same time
76     * not changing any statistical properties. So we use the same
77     * underlying multiplicative sequence, but start the sequence far
78     * away from the base version, and then merge (xor) current time
79     * and per-thread probe bits to generate initial values.
80     *
81     * The nextLocalGaussian ThreadLocal supports the very rarely used
82     * nextGaussian method by providing a holder for the second of a
83     * pair of them. As is true for the base class version of this
84     * method, this time/space tradeoff is probably never worthwhile,
85     * but we provide identical statistical properties.
86     */
87    
88 jsr166 1.1 // same constants as Random, but must be redeclared because private
89 jsr166 1.5 private static final long multiplier = 0x5DEECE66DL;
90     private static final long addend = 0xBL;
91     private static final long mask = (1L << 48) - 1;
92 dl 1.7 private static final int PROBE_INCREMENT = 0x61c88647;
93 jsr166 1.1
94 dl 1.7 /** Generates the basis for per-thread initial seed values */
95     private static final AtomicLong seedGenerator =
96     new AtomicLong(1269533684904616924L);
97 jsr166 1.1
98 dl 1.7 /** Generates per-thread initialization/probe field */
99     private static final AtomicInteger probeGenerator =
100     new AtomicInteger(0xe80f8647);
101 jsr166 1.1
102 dl 1.7 /** Rarely-used holder for the second of a pair of Gaussians */
103     private static final ThreadLocal<Double> nextLocalGaussian =
104     new ThreadLocal<Double>();
105 jsr166 1.1
106 jsr166 1.11 /**
107     * Field used only during singleton initialization.
108     * True when constructor completes.
109 jsr166 1.1 */
110 jsr166 1.11 boolean initialized;
111 dl 1.7
112     /** Constructor used only for static singleton */
113     private ThreadLocalRandom() {
114     initialized = true; // false during super() call
115     }
116 jsr166 1.1
117 dl 1.7 /** The common ThreadLocalRandom */
118     static final ThreadLocalRandom instance = new ThreadLocalRandom();
119 jsr166 1.1
120     /**
121 dl 1.7 * Initialize Thread fields for the current thread. Called only
122     * when Thread.threadLocalRandomProbe is zero, indicating that a
123     * thread local seed value needs to be generated. Note that even
124     * though the initialization is purely thread-local, we need to
125     * rely on (static) atomic generators to initialize the values.
126     */
127     static final void localInit() {
128     int p = probeGenerator.getAndAdd(PROBE_INCREMENT);
129     int probe = (p == 0) ? 1 : p; // skip 0
130     long current, next;
131     do { // same sequence as j.u.Random but different initial value
132     current = seedGenerator.get();
133     next = current * 181783497276652981L;
134     } while (!seedGenerator.compareAndSet(current, next));
135     long r = next ^ ((long)probe << 32) ^ System.nanoTime();
136     Thread t = Thread.currentThread();
137     UNSAFE.putLong(t, SEED, r);
138     UNSAFE.putInt(t, PROBE, probe);
139 jsr166 1.1 }
140    
141     /**
142 jsr166 1.3 * Returns the current thread's {@code ThreadLocalRandom}.
143 jsr166 1.1 *
144 jsr166 1.3 * @return the current thread's {@code ThreadLocalRandom}
145 jsr166 1.1 */
146     public static ThreadLocalRandom current() {
147 dl 1.7 if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
148     localInit();
149     return instance;
150 jsr166 1.1 }
151    
152     /**
153 jsr166 1.3 * Throws {@code UnsupportedOperationException}. Setting seeds in
154     * this generator is not supported.
155 jsr166 1.1 *
156     * @throws UnsupportedOperationException always
157     */
158     public void setSeed(long seed) {
159 dl 1.7 if (initialized) // allow call from super() constructor
160 jsr166 1.1 throw new UnsupportedOperationException();
161     }
162    
163     protected int next(int bits) {
164 dl 1.7 Thread t; long r; // read and update per-thread seed
165     UNSAFE.putLong
166     (t = Thread.currentThread(), SEED,
167     r = (UNSAFE.getLong(t, SEED) * multiplier + addend) & mask);
168     return (int) (r >>> (48-bits));
169 jsr166 1.1 }
170    
171     /**
172     * Returns a pseudorandom, uniformly distributed value between the
173     * given least value (inclusive) and bound (exclusive).
174     *
175     * @param least the least value returned
176     * @param bound the upper bound (exclusive)
177     * @throws IllegalArgumentException if least greater than or equal
178     * to bound
179     * @return the next value
180     */
181     public int nextInt(int least, int bound) {
182     if (least >= bound)
183     throw new IllegalArgumentException();
184     return nextInt(bound - least) + least;
185     }
186    
187     /**
188     * Returns a pseudorandom, uniformly distributed value
189     * between 0 (inclusive) and the specified value (exclusive).
190     *
191     * @param n the bound on the random number to be returned. Must be
192     * positive.
193     * @return the next value
194     * @throws IllegalArgumentException if n is not positive
195     */
196     public long nextLong(long n) {
197     if (n <= 0)
198     throw new IllegalArgumentException("n must be positive");
199     // Divide n by two until small enough for nextInt. On each
200     // iteration (at most 31 of them but usually much less),
201     // randomly choose both whether to include high bit in result
202     // (offset) and whether to continue with the lower vs upper
203     // half (which makes a difference only if odd).
204     long offset = 0;
205     while (n >= Integer.MAX_VALUE) {
206     int bits = next(2);
207     long half = n >>> 1;
208     long nextn = ((bits & 2) == 0) ? half : n - half;
209     if ((bits & 1) == 0)
210     offset += n - nextn;
211     n = nextn;
212     }
213     return offset + nextInt((int) n);
214     }
215    
216     /**
217     * Returns a pseudorandom, uniformly distributed value between the
218     * given least value (inclusive) and bound (exclusive).
219     *
220     * @param least the least value returned
221     * @param bound the upper bound (exclusive)
222     * @return the next value
223     * @throws IllegalArgumentException if least greater than or equal
224     * to bound
225     */
226     public long nextLong(long least, long bound) {
227     if (least >= bound)
228     throw new IllegalArgumentException();
229     return nextLong(bound - least) + least;
230     }
231    
232     /**
233     * Returns a pseudorandom, uniformly distributed {@code double} value
234     * between 0 (inclusive) and the specified value (exclusive).
235     *
236     * @param n the bound on the random number to be returned. Must be
237     * positive.
238     * @return the next value
239     * @throws IllegalArgumentException if n is not positive
240     */
241     public double nextDouble(double n) {
242     if (n <= 0)
243     throw new IllegalArgumentException("n must be positive");
244     return nextDouble() * n;
245     }
246    
247     /**
248     * Returns a pseudorandom, uniformly distributed value between the
249     * given least value (inclusive) and bound (exclusive).
250     *
251     * @param least the least value returned
252     * @param bound the upper bound (exclusive)
253     * @return the next value
254     * @throws IllegalArgumentException if least greater than or equal
255     * to bound
256     */
257     public double nextDouble(double least, double bound) {
258     if (least >= bound)
259     throw new IllegalArgumentException();
260     return nextDouble() * (bound - least) + least;
261     }
262    
263 dl 1.7 public double nextGaussian() {
264     // Use nextLocalGaussian instead of nextGaussian field
265     Double d = nextLocalGaussian.get();
266     if (d != null) {
267     nextLocalGaussian.set(null);
268     return d.doubleValue();
269     }
270     double v1, v2, s;
271     do {
272     v1 = 2 * nextDouble() - 1; // between -1 and 1
273     v2 = 2 * nextDouble() - 1; // between -1 and 1
274     s = v1 * v1 + v2 * v2;
275     } while (s >= 1 || s == 0);
276     double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
277     nextLocalGaussian.set(new Double(v2 * multiplier));
278     return v1 * multiplier;
279     }
280    
281     // Within-package utilities
282    
283     /*
284     * Descriptions of the usages of the methods below can be found in
285     * the classes that use them. Briefly, a thread's "probe" value is
286     * a non-zero hash code that (probably) does not collide with
287     * other existing threads with respect to any power of two
288     * collision space. When it does collide, it is pseudo-randomly
289     * adjusted (using a Marsaglia XorShift). The nextSecondarySeed
290     * method is used in the same contexts as ThreadLocalRandom, but
291     * only for transient usages such as random adaptive spin/block
292     * sequences for which a cheap RNG suffices and for which it could
293     * in principle disrupt user-visible statistical properties of the
294     * main ThreadLocalRandom if we were to use it.
295     *
296     * Note: Because of package-protection issues, versions of some
297 dl 1.9 * these methods also appear in some subpackage classes.
298 dl 1.7 */
299    
300     /**
301     * Returns the probe value for the current thread without forcing
302     * initialization. Note that invoking ThreadLocalRandom.current()
303     * can be used to force initialization on zero return.
304     */
305     static final int getProbe() {
306     return UNSAFE.getInt(Thread.currentThread(), PROBE);
307     }
308    
309     /**
310     * Pseudo-randomly advances and records the given probe value for the
311     * given thread.
312     */
313     static final int advanceProbe(int probe) {
314     probe ^= probe << 13; // xorshift
315     probe ^= probe >>> 17;
316     probe ^= probe << 5;
317     UNSAFE.putInt(Thread.currentThread(), PROBE, probe);
318     return probe;
319     }
320    
321     /**
322     * Returns the pseudo-randomly initialized or updated secondary seed.
323     */
324     static final int nextSecondarySeed() {
325     int r;
326     Thread t = Thread.currentThread();
327     if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
328     r ^= r << 13; // xorshift
329     r ^= r >>> 17;
330     r ^= r << 5;
331     }
332 dl 1.10 else {
333     localInit();
334     if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
335     r = 1; // avoid zero
336     }
337 dl 1.7 UNSAFE.putInt(t, SECONDARY, r);
338     return r;
339     }
340    
341 dl 1.9 // Serialization support, maintains original persistent form.
342    
343 jsr166 1.1 private static final long serialVersionUID = -5851777807851030925L;
344 dl 1.7
345 dl 1.9 /**
346     * @serialField rnd long
347     * @serialField initialized boolean
348     * @serialField pad0 long
349     * @serialField pad1 long
350     * @serialField pad2 long
351     * @serialField pad3 long
352     * @serialField pad4 long
353     * @serialField pad5 long
354     * @serialField pad6 long
355     * @serialField pad7 long
356     */
357     private static final ObjectStreamField[] serialPersistentFields = {
358     new ObjectStreamField("rnd", long.class),
359     new ObjectStreamField("initialized", boolean.class),
360     new ObjectStreamField("pad0", long.class),
361     new ObjectStreamField("pad1", long.class),
362     new ObjectStreamField("pad2", long.class),
363     new ObjectStreamField("pad3", long.class),
364     new ObjectStreamField("pad4", long.class),
365     new ObjectStreamField("pad5", long.class),
366     new ObjectStreamField("pad6", long.class),
367     new ObjectStreamField("pad7", long.class) };
368    
369     /**
370     * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
371     */
372     private void writeObject(java.io.ObjectOutputStream out)
373     throws java.io.IOException {
374    
375     java.io.ObjectOutputStream.PutField fields = out.putFields();
376     fields.put("rnd", 0L);
377     fields.put("initialized", true);
378     fields.put("pad0", 0L);
379     fields.put("pad1", 0L);
380     fields.put("pad2", 0L);
381     fields.put("pad3", 0L);
382     fields.put("pad4", 0L);
383     fields.put("pad5", 0L);
384     fields.put("pad6", 0L);
385     fields.put("pad7", 0L);
386     out.writeFields();
387     }
388    
389     /**
390     * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
391     */
392     private Object readResolve() {
393     return current();
394     }
395    
396 dl 1.7 // Unsafe mechanics
397     private static final sun.misc.Unsafe UNSAFE;
398     private static final long SEED;
399     private static final long PROBE;
400     private static final long SECONDARY;
401     static {
402     try {
403     UNSAFE = sun.misc.Unsafe.getUnsafe();
404     Class<?> tk = Thread.class;
405     SEED = UNSAFE.objectFieldOffset
406     (tk.getDeclaredField("threadLocalRandomSeed"));
407     PROBE = UNSAFE.objectFieldOffset
408     (tk.getDeclaredField("threadLocalRandomProbe"));
409     SECONDARY = UNSAFE.objectFieldOffset
410     (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
411     } catch (Exception e) {
412     throw new Error(e);
413     }
414     }
415 jsr166 1.1 }