ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ThreadLocalRandom.java
Revision: 1.2
Committed: Fri Jul 19 19:34:43 2013 UTC (10 years, 8 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +1 -1 lines
Log Message:
enforce standard javadoc tag order

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