ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/ThreadLocalRandom.java
Revision: 1.3
Committed: Thu Mar 19 06:50:01 2009 UTC (15 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.2: +8 -8 lines
Log Message:
fix javadoc warning

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/licenses/publicdomain
5 */
6
7 package jsr166y;
8 import java.util.*;
9
10 /**
11 * A random number generator with the same properties as class {@link
12 * Random} but isolated to the current Thread. Like the global
13 * generator used by the {@link java.lang.Math} class, a
14 * ThreadLocalRandom is initialized with an internally generated seed
15 * that may not otherwise be modified. When applicable, use of
16 * ThreadLocalRandom rather than shared Random objects in concurrent
17 * programs will typically encounter much less overhead and
18 * contention. ThreadLocalRandoms are particularly appropriate when
19 * multiple tasks (for example, each a {@link ForkJoinTask}), use
20 * random numbers in parallel in thread pools.
21 *
22 * <p>Usages of this class should typically be of the form:
23 * <code>ThreadLocalRandom.current().nextX(...)</code> (where
24 * <code>X</code> is <code>Int</code>, <code>Long</code>, etc).
25 * When all usages are of this form, it is never possible to
26 * accidently share ThreadLocalRandoms across multiple threads.
27 *
28 * <p>This class also provides additional commonly used bounded random
29 * generation methods.
30 */
31 public class ThreadLocalRandom extends Random {
32 // same constants as Random, but must be redeclared because private
33 private final static long multiplier = 0x5DEECE66DL;
34 private final static long addend = 0xBL;
35 private final static long mask = (1L << 48) - 1;
36
37 /**
38 * The random seed. We can't use super.seed
39 */
40 private long rnd;
41
42 /**
43 * Initialization flag to permit the first and only allowed call
44 * to setSeed (inside Random constructor) to succeed. We can't
45 * allow others since it would cause setting seed in one part of a
46 * program to unintentionally impact other usages by the thread.
47 */
48 boolean initialized;
49
50 // Padding to help avoid memory contention among seed updates in
51 // different TLRs in the common case that they are located near
52 // each other.
53 private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
54
55 /**
56 * The actual ThreadLocal
57 */
58 private static final ThreadLocal<ThreadLocalRandom> localRandom =
59 new ThreadLocal<ThreadLocalRandom>() {
60 protected ThreadLocalRandom initialValue() {
61 return new ThreadLocalRandom();
62 }
63 };
64
65
66 /**
67 * Constructor called only by localRandom.initialValue.
68 * We rely on the fact that the superclass no-arg constructor
69 * invokes setSeed exactly once to initialize.
70 */
71 ThreadLocalRandom() {
72 super();
73 }
74
75 /**
76 * Returns the current Thread's ThreadLocalRandom
77 * @return the current Thread's ThreadLocalRandom
78 */
79 public static ThreadLocalRandom current() {
80 return localRandom.get();
81 }
82
83 /**
84 * Throws UnsupportedOperationException. Setting seeds in this
85 * generator is unsupported.
86 * @throws UnsupportedOperationException always
87 */
88 public void setSeed(long seed) {
89 if (initialized)
90 throw new UnsupportedOperationException();
91 initialized = true;
92 rnd = (seed ^ multiplier) & mask;
93 }
94
95 protected int next(int bits) {
96 return (int)((rnd = (rnd * multiplier + addend) & mask) >>> (48-bits));
97 }
98
99 /**
100 * Returns a pseudorandom, uniformly distributed value between the
101 * given least value (inclusive) and bound (exclusive).
102 * @param least the least value returned
103 * @param bound the upper bound (exclusive)
104 * @throws IllegalArgumentException if least greater than or equal
105 * to bound
106 * @return the next value
107 */
108 public int nextInt(int least, int bound) {
109 if (least >= bound)
110 throw new IllegalArgumentException();
111 return nextInt(bound - least) + least;
112 }
113
114 /**
115 * Returns a pseudorandom, uniformly distributed value
116 * between 0 (inclusive) and the specified value (exclusive)
117 * @param n the bound on the random number to be returned. Must be
118 * positive.
119 * @return the next value
120 * @throws IllegalArgumentException if n is not positive
121 */
122 public long nextLong(long n) {
123 if (n <= 0)
124 throw new IllegalArgumentException("n must be positive");
125 // Divide n by two until small enough for nextInt. On each
126 // iteration (at most 31 of them but usually much less),
127 // randomly choose both whether to include high bit in result
128 // (offset) and whether to continue with the lower vs upper
129 // half (which makes a difference only if odd).
130 long offset = 0;
131 while (n >= Integer.MAX_VALUE) {
132 int bits = next(2);
133 long half = n >>> 1;
134 long nextn = ((bits & 2) == 0)? half : n - half;
135 if ((bits & 1) == 0)
136 offset += n - nextn;
137 n = nextn;
138 }
139 return offset + nextInt((int)n);
140 }
141
142 /**
143 * Returns a pseudorandom, uniformly distributed value between the
144 * given least value (inclusive) and bound (exclusive).
145 * @param least the least value returned
146 * @param bound the upper bound (exclusive)
147 * @return the next value
148 * @throws IllegalArgumentException if least greater than or equal
149 * to bound
150 */
151 public long nextLong(long least, long bound) {
152 if (least >= bound)
153 throw new IllegalArgumentException();
154 return nextLong(bound - least) + least;
155 }
156
157 /**
158 * Returns a pseudorandom, uniformly distributed {@code double} value
159 * between 0 (inclusive) and the specified value (exclusive)
160 * @param n the bound on the random number to be returned. Must be
161 * positive.
162 * @return the next value
163 * @throws IllegalArgumentException if n is not positive
164 */
165 public double nextDouble(double n) {
166 if (n <= 0)
167 throw new IllegalArgumentException("n must be positive");
168 return nextDouble() * n;
169 }
170
171 /**
172 * Returns a pseudorandom, uniformly distributed value between the
173 * given least value (inclusive) and bound (exclusive).
174 * @param least the least value returned
175 * @param bound the upper bound (exclusive)
176 * @return the next value
177 * @throws IllegalArgumentException if least greater than or equal
178 * to bound
179 */
180 public double nextDouble(double least, double bound) {
181 if (least >= bound)
182 throw new IllegalArgumentException();
183 return nextDouble() * (bound - least) + least;
184 }
185
186 }