ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.14
Committed: Mon Feb 25 22:26:49 2013 UTC (11 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.13: +23 -0 lines
Log Message:
reinstate @serialFields and writeObject, but un-padded

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 jsr166 1.13 // Serialization support
342 dl 1.9
343 jsr166 1.1 private static final long serialVersionUID = -5851777807851030925L;
344 dl 1.7
345 dl 1.9 /**
346 jsr166 1.14 * @serialField rnd long
347     * seed for random computations
348     * @serialField initialized boolean
349     * always true
350     */
351     private static final ObjectStreamField[] serialPersistentFields = {
352     new ObjectStreamField("rnd", long.class),
353     new ObjectStreamField("initialized", boolean.class),
354     };
355    
356     /**
357     * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
358     */
359     private void writeObject(java.io.ObjectOutputStream out)
360     throws java.io.IOException {
361    
362     java.io.ObjectOutputStream.PutField fields = out.putFields();
363     fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
364     fields.put("initialized", true);
365     out.writeFields();
366     }
367    
368     /**
369 dl 1.9 * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
370     */
371     private Object readResolve() {
372     return current();
373     }
374    
375 dl 1.7 // Unsafe mechanics
376     private static final sun.misc.Unsafe UNSAFE;
377     private static final long SEED;
378     private static final long PROBE;
379     private static final long SECONDARY;
380     static {
381     try {
382     UNSAFE = sun.misc.Unsafe.getUnsafe();
383     Class<?> tk = Thread.class;
384     SEED = UNSAFE.objectFieldOffset
385     (tk.getDeclaredField("threadLocalRandomSeed"));
386     PROBE = UNSAFE.objectFieldOffset
387     (tk.getDeclaredField("threadLocalRandomProbe"));
388     SECONDARY = UNSAFE.objectFieldOffset
389     (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
390     } catch (Exception e) {
391     throw new Error(e);
392     }
393     }
394 jsr166 1.1 }