ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/ThreadLocalRandom.java
Revision: 1.8
Committed: Thu Jul 23 23:07:57 2009 UTC (14 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.7: +13 -5 lines
Log Message:
j.u.c. coding standards

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(...)} (where
24 * {@code X} is {@code Int}, {@code Long}, 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 * @since 1.7
32 * @author Doug Lea
33 */
34 public class ThreadLocalRandom extends Random {
35 // same constants as Random, but must be redeclared because private
36 private final static long multiplier = 0x5DEECE66DL;
37 private final static long addend = 0xBL;
38 private final static long mask = (1L << 48) - 1;
39
40 /**
41 * The random seed. We can't use super.seed.
42 */
43 private long rnd;
44
45 /**
46 * Initialization flag to permit the first and only allowed call
47 * to setSeed (inside Random constructor) to succeed. We can't
48 * allow others since it would cause setting seed in one part of a
49 * program to unintentionally impact other usages by the thread.
50 */
51 boolean initialized;
52
53 // Padding to help avoid memory contention among seed updates in
54 // different TLRs in the common case that they are located near
55 // each other.
56 private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
57
58 /**
59 * The actual ThreadLocal
60 */
61 private static final ThreadLocal<ThreadLocalRandom> localRandom =
62 new ThreadLocal<ThreadLocalRandom>() {
63 protected ThreadLocalRandom initialValue() {
64 return new ThreadLocalRandom();
65 }
66 };
67
68
69 /**
70 * Constructor called only by localRandom.initialValue.
71 * We rely on the fact that the superclass no-arg constructor
72 * invokes setSeed exactly once to initialize.
73 */
74 ThreadLocalRandom() {
75 super();
76 }
77
78 /**
79 * Returns the current Thread's ThreadLocalRandom.
80 *
81 * @return the current Thread's ThreadLocalRandom
82 */
83 public static ThreadLocalRandom current() {
84 return localRandom.get();
85 }
86
87 /**
88 * Throws UnsupportedOperationException. Setting seeds in this
89 * generator is unsupported.
90 *
91 * @throws UnsupportedOperationException always
92 */
93 public void setSeed(long seed) {
94 if (initialized)
95 throw new UnsupportedOperationException();
96 initialized = true;
97 rnd = (seed ^ multiplier) & mask;
98 }
99
100 protected int next(int bits) {
101 rnd = (rnd * multiplier + addend) & mask;
102 return (int) (rnd >>> (48-bits));
103 }
104
105 /**
106 * Returns a pseudorandom, uniformly distributed value between the
107 * given least value (inclusive) and bound (exclusive).
108 *
109 * @param least the least value returned
110 * @param bound the upper bound (exclusive)
111 * @throws IllegalArgumentException if least greater than or equal
112 * to bound
113 * @return the next value
114 */
115 public int nextInt(int least, int bound) {
116 if (least >= bound)
117 throw new IllegalArgumentException();
118 return nextInt(bound - least) + least;
119 }
120
121 /**
122 * Returns a pseudorandom, uniformly distributed value
123 * between 0 (inclusive) and the specified value (exclusive).
124 *
125 * @param n the bound on the random number to be returned. Must be
126 * positive.
127 * @return the next value
128 * @throws IllegalArgumentException if n is not positive
129 */
130 public long nextLong(long n) {
131 if (n <= 0)
132 throw new IllegalArgumentException("n must be positive");
133 // Divide n by two until small enough for nextInt. On each
134 // iteration (at most 31 of them but usually much less),
135 // randomly choose both whether to include high bit in result
136 // (offset) and whether to continue with the lower vs upper
137 // half (which makes a difference only if odd).
138 long offset = 0;
139 while (n >= Integer.MAX_VALUE) {
140 int bits = next(2);
141 long half = n >>> 1;
142 long nextn = ((bits & 2) == 0) ? half : n - half;
143 if ((bits & 1) == 0)
144 offset += n - nextn;
145 n = nextn;
146 }
147 return offset + nextInt((int) n);
148 }
149
150 /**
151 * Returns a pseudorandom, uniformly distributed value between the
152 * given least value (inclusive) and bound (exclusive).
153 *
154 * @param least the least value returned
155 * @param bound the upper bound (exclusive)
156 * @return the next value
157 * @throws IllegalArgumentException if least greater than or equal
158 * to bound
159 */
160 public long nextLong(long least, long bound) {
161 if (least >= bound)
162 throw new IllegalArgumentException();
163 return nextLong(bound - least) + least;
164 }
165
166 /**
167 * Returns a pseudorandom, uniformly distributed {@code double} value
168 * between 0 (inclusive) and the specified value (exclusive).
169 *
170 * @param n the bound on the random number to be returned. Must be
171 * positive.
172 * @return the next value
173 * @throws IllegalArgumentException if n is not positive
174 */
175 public double nextDouble(double n) {
176 if (n <= 0)
177 throw new IllegalArgumentException("n must be positive");
178 return nextDouble() * n;
179 }
180
181 /**
182 * Returns a pseudorandom, uniformly distributed value between the
183 * given least value (inclusive) and bound (exclusive).
184 *
185 * @param least the least value returned
186 * @param bound the upper bound (exclusive)
187 * @return the next value
188 * @throws IllegalArgumentException if least greater than or equal
189 * to bound
190 */
191 public double nextDouble(double least, double bound) {
192 if (least >= bound)
193 throw new IllegalArgumentException();
194 return nextDouble() * (bound - least) + least;
195 }
196
197 }