ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.9
Committed: Wed Jan 16 15:04:04 2013 UTC (11 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.8: +56 -3 lines
Log Message:
lambda-lib support

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 dl 1.7 /*
107 dl 1.9 * Field used only during singleton initialization
108 jsr166 1.1 */
109 dl 1.7 boolean initialized; // true when constructor completes
110    
111     /** Constructor used only for static singleton */
112     private ThreadLocalRandom() {
113     initialized = true; // false during super() call
114     }
115 jsr166 1.1
116 dl 1.7 /** The common ThreadLocalRandom */
117     static final ThreadLocalRandom instance = new ThreadLocalRandom();
118 jsr166 1.1
119     /**
120 dl 1.7 * Initialize Thread fields for the current thread. Called only
121     * when Thread.threadLocalRandomProbe is zero, indicating that a
122     * thread local seed value needs to be generated. Note that even
123     * though the initialization is purely thread-local, we need to
124     * rely on (static) atomic generators to initialize the values.
125     */
126     static final void localInit() {
127     int p = probeGenerator.getAndAdd(PROBE_INCREMENT);
128     int probe = (p == 0) ? 1 : p; // skip 0
129     long current, next;
130     do { // same sequence as j.u.Random but different initial value
131     current = seedGenerator.get();
132     next = current * 181783497276652981L;
133     } while (!seedGenerator.compareAndSet(current, next));
134     long r = next ^ ((long)probe << 32) ^ System.nanoTime();
135     Thread t = Thread.currentThread();
136     UNSAFE.putLong(t, SEED, r);
137     UNSAFE.putInt(t, PROBE, probe);
138 jsr166 1.1 }
139    
140     /**
141 jsr166 1.3 * Returns the current thread's {@code ThreadLocalRandom}.
142 jsr166 1.1 *
143 jsr166 1.3 * @return the current thread's {@code ThreadLocalRandom}
144 jsr166 1.1 */
145     public static ThreadLocalRandom current() {
146 dl 1.7 if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
147     localInit();
148     return instance;
149 jsr166 1.1 }
150    
151     /**
152 jsr166 1.3 * Throws {@code UnsupportedOperationException}. Setting seeds in
153     * this generator is not supported.
154 jsr166 1.1 *
155     * @throws UnsupportedOperationException always
156     */
157     public void setSeed(long seed) {
158 dl 1.7 if (initialized) // allow call from super() constructor
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     * @throws IllegalArgumentException if least greater than or equal
177     * to bound
178     * @return the next value
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     else if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
332     r = 1; // avoid zero
333     UNSAFE.putInt(t, SECONDARY, r);
334     return r;
335     }
336    
337 dl 1.9 // Serialization support, maintains original persistent form.
338    
339 jsr166 1.1 private static final long serialVersionUID = -5851777807851030925L;
340 dl 1.7
341 dl 1.9 /**
342     * @serialField rnd long
343     * @serialField initialized boolean
344     * @serialField pad0 long
345     * @serialField pad1 long
346     * @serialField pad2 long
347     * @serialField pad3 long
348     * @serialField pad4 long
349     * @serialField pad5 long
350     * @serialField pad6 long
351     * @serialField pad7 long
352     */
353     private static final ObjectStreamField[] serialPersistentFields = {
354     new ObjectStreamField("rnd", long.class),
355     new ObjectStreamField("initialized", boolean.class),
356     new ObjectStreamField("pad0", long.class),
357     new ObjectStreamField("pad1", long.class),
358     new ObjectStreamField("pad2", long.class),
359     new ObjectStreamField("pad3", long.class),
360     new ObjectStreamField("pad4", long.class),
361     new ObjectStreamField("pad5", long.class),
362     new ObjectStreamField("pad6", long.class),
363     new ObjectStreamField("pad7", long.class) };
364    
365     /**
366     * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
367     */
368     private void writeObject(java.io.ObjectOutputStream out)
369     throws java.io.IOException {
370    
371     java.io.ObjectOutputStream.PutField fields = out.putFields();
372     fields.put("rnd", 0L);
373     fields.put("initialized", true);
374     fields.put("pad0", 0L);
375     fields.put("pad1", 0L);
376     fields.put("pad2", 0L);
377     fields.put("pad3", 0L);
378     fields.put("pad4", 0L);
379     fields.put("pad5", 0L);
380     fields.put("pad6", 0L);
381     fields.put("pad7", 0L);
382     out.writeFields();
383     }
384    
385     /**
386     * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
387     */
388     private Object readResolve() {
389     return current();
390     }
391    
392 dl 1.7 // Unsafe mechanics
393     private static final sun.misc.Unsafe UNSAFE;
394     private static final long SEED;
395     private static final long PROBE;
396     private static final long SECONDARY;
397     static {
398     try {
399     UNSAFE = sun.misc.Unsafe.getUnsafe();
400     Class<?> tk = Thread.class;
401     SEED = UNSAFE.objectFieldOffset
402     (tk.getDeclaredField("threadLocalRandomSeed"));
403     PROBE = UNSAFE.objectFieldOffset
404     (tk.getDeclaredField("threadLocalRandomProbe"));
405     SECONDARY = UNSAFE.objectFieldOffset
406     (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
407     } catch (Exception e) {
408     throw new Error(e);
409     }
410     }
411 jsr166 1.1 }