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

# Content
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 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package java.util.concurrent;
8
9 import java.io.ObjectStreamField;
10 import java.util.Random;
11 import java.util.concurrent.atomic.AtomicInteger;
12 import java.util.concurrent.atomic.AtomicLong;
13
14 /**
15 * A random number generator isolated to the current thread. Like the
16 * global {@link java.util.Random} generator used by the {@link
17 * 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 *
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 * accidently share a {@code ThreadLocalRandom} across multiple threads.
31 *
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 /*
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 // same constants as Random, but must be redeclared because private
89 private static final long multiplier = 0x5DEECE66DL;
90 private static final long addend = 0xBL;
91 private static final long mask = (1L << 48) - 1;
92 private static final int PROBE_INCREMENT = 0x61c88647;
93
94 /** Generates the basis for per-thread initial seed values */
95 private static final AtomicLong seedGenerator =
96 new AtomicLong(1269533684904616924L);
97
98 /** Generates per-thread initialization/probe field */
99 private static final AtomicInteger probeGenerator =
100 new AtomicInteger(0xe80f8647);
101
102 /** Rarely-used holder for the second of a pair of Gaussians */
103 private static final ThreadLocal<Double> nextLocalGaussian =
104 new ThreadLocal<Double>();
105
106 /**
107 * Field used only during singleton initialization.
108 * True when constructor completes.
109 */
110 boolean initialized;
111
112 /** Constructor used only for static singleton */
113 private ThreadLocalRandom() {
114 initialized = true; // false during super() call
115 }
116
117 /** The common ThreadLocalRandom */
118 static final ThreadLocalRandom instance = new ThreadLocalRandom();
119
120 /**
121 * 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 }
140
141 /**
142 * Returns the current thread's {@code ThreadLocalRandom}.
143 *
144 * @return the current thread's {@code ThreadLocalRandom}
145 */
146 public static ThreadLocalRandom current() {
147 if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
148 localInit();
149 return instance;
150 }
151
152 /**
153 * Throws {@code UnsupportedOperationException}. Setting seeds in
154 * this generator is not supported.
155 *
156 * @throws UnsupportedOperationException always
157 */
158 public void setSeed(long seed) {
159 if (initialized) // allow call from super() constructor
160 throw new UnsupportedOperationException();
161 }
162
163 protected int next(int bits) {
164 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 }
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 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 * these methods also appear in some subpackage classes.
298 */
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 else {
333 localInit();
334 if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
335 r = 1; // avoid zero
336 }
337 UNSAFE.putInt(t, SECONDARY, r);
338 return r;
339 }
340
341 // Serialization support, maintains original persistent form.
342
343 private static final long serialVersionUID = -5851777807851030925L;
344
345 /**
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 // 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 }