ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.10
Committed: Tue Jan 22 17:17:52 2013 UTC (11 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.9: +5 -2 lines
Log Message:
Auto-initializae in secondarySeed

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 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 dl 1.9 // Serialization support, maintains original persistent form.
341    
342 jsr166 1.1 private static final long serialVersionUID = -5851777807851030925L;
343 dl 1.7
344 dl 1.9 /**
345     * @serialField rnd long
346     * @serialField initialized boolean
347     * @serialField pad0 long
348     * @serialField pad1 long
349     * @serialField pad2 long
350     * @serialField pad3 long
351     * @serialField pad4 long
352     * @serialField pad5 long
353     * @serialField pad6 long
354     * @serialField pad7 long
355     */
356     private static final ObjectStreamField[] serialPersistentFields = {
357     new ObjectStreamField("rnd", long.class),
358     new ObjectStreamField("initialized", boolean.class),
359     new ObjectStreamField("pad0", long.class),
360     new ObjectStreamField("pad1", long.class),
361     new ObjectStreamField("pad2", long.class),
362     new ObjectStreamField("pad3", long.class),
363     new ObjectStreamField("pad4", long.class),
364     new ObjectStreamField("pad5", long.class),
365     new ObjectStreamField("pad6", long.class),
366     new ObjectStreamField("pad7", long.class) };
367    
368     /**
369     * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
370     */
371     private void writeObject(java.io.ObjectOutputStream out)
372     throws java.io.IOException {
373    
374     java.io.ObjectOutputStream.PutField fields = out.putFields();
375     fields.put("rnd", 0L);
376     fields.put("initialized", true);
377     fields.put("pad0", 0L);
378     fields.put("pad1", 0L);
379     fields.put("pad2", 0L);
380     fields.put("pad3", 0L);
381     fields.put("pad4", 0L);
382     fields.put("pad5", 0L);
383     fields.put("pad6", 0L);
384     fields.put("pad7", 0L);
385     out.writeFields();
386     }
387    
388     /**
389     * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
390     */
391     private Object readResolve() {
392     return current();
393     }
394    
395 dl 1.7 // Unsafe mechanics
396     private static final sun.misc.Unsafe UNSAFE;
397     private static final long SEED;
398     private static final long PROBE;
399     private static final long SECONDARY;
400     static {
401     try {
402     UNSAFE = sun.misc.Unsafe.getUnsafe();
403     Class<?> tk = Thread.class;
404     SEED = UNSAFE.objectFieldOffset
405     (tk.getDeclaredField("threadLocalRandomSeed"));
406     PROBE = UNSAFE.objectFieldOffset
407     (tk.getDeclaredField("threadLocalRandomProbe"));
408     SECONDARY = UNSAFE.objectFieldOffset
409     (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
410     } catch (Exception e) {
411     throw new Error(e);
412     }
413     }
414 jsr166 1.1 }