ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/ThreadLocalRandom.java
Revision: 1.7
Committed: Thu Jul 23 19:25:45 2009 UTC (14 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.6: +1 -1 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 * @return the current Thread's ThreadLocalRandom
81 */
82 public static ThreadLocalRandom current() {
83 return localRandom.get();
84 }
85
86 /**
87 * Throws UnsupportedOperationException. Setting seeds in this
88 * generator is unsupported.
89 * @throws UnsupportedOperationException always
90 */
91 public void setSeed(long seed) {
92 if (initialized)
93 throw new UnsupportedOperationException();
94 initialized = true;
95 rnd = (seed ^ multiplier) & mask;
96 }
97
98 protected int next(int bits) {
99 return (int)((rnd = (rnd * multiplier + addend) & mask) >>> (48-bits));
100 }
101
102 /**
103 * Returns a pseudorandom, uniformly distributed value between the
104 * given least value (inclusive) and bound (exclusive).
105 * @param least the least value returned
106 * @param bound the upper bound (exclusive)
107 * @throws IllegalArgumentException if least greater than or equal
108 * to bound
109 * @return the next value
110 */
111 public int nextInt(int least, int bound) {
112 if (least >= bound)
113 throw new IllegalArgumentException();
114 return nextInt(bound - least) + least;
115 }
116
117 /**
118 * Returns a pseudorandom, uniformly distributed value
119 * between 0 (inclusive) and the specified value (exclusive)
120 * @param n the bound on the random number to be returned. Must be
121 * positive.
122 * @return the next value
123 * @throws IllegalArgumentException if n is not positive
124 */
125 public long nextLong(long n) {
126 if (n <= 0)
127 throw new IllegalArgumentException("n must be positive");
128 // Divide n by two until small enough for nextInt. On each
129 // iteration (at most 31 of them but usually much less),
130 // randomly choose both whether to include high bit in result
131 // (offset) and whether to continue with the lower vs upper
132 // half (which makes a difference only if odd).
133 long offset = 0;
134 while (n >= Integer.MAX_VALUE) {
135 int bits = next(2);
136 long half = n >>> 1;
137 long nextn = ((bits & 2) == 0)? half : n - half;
138 if ((bits & 1) == 0)
139 offset += n - nextn;
140 n = nextn;
141 }
142 return offset + nextInt((int) n);
143 }
144
145 /**
146 * Returns a pseudorandom, uniformly distributed value between the
147 * given least value (inclusive) and bound (exclusive).
148 * @param least the least value returned
149 * @param bound the upper bound (exclusive)
150 * @return the next value
151 * @throws IllegalArgumentException if least greater than or equal
152 * to bound
153 */
154 public long nextLong(long least, long bound) {
155 if (least >= bound)
156 throw new IllegalArgumentException();
157 return nextLong(bound - least) + least;
158 }
159
160 /**
161 * Returns a pseudorandom, uniformly distributed {@code double} value
162 * between 0 (inclusive) and the specified value (exclusive)
163 * @param n the bound on the random number to be returned. Must be
164 * positive.
165 * @return the next value
166 * @throws IllegalArgumentException if n is not positive
167 */
168 public double nextDouble(double n) {
169 if (n <= 0)
170 throw new IllegalArgumentException("n must be positive");
171 return nextDouble() * n;
172 }
173
174 /**
175 * Returns a pseudorandom, uniformly distributed value between the
176 * given least value (inclusive) and bound (exclusive).
177 * @param least the least value returned
178 * @param bound the upper bound (exclusive)
179 * @return the next value
180 * @throws IllegalArgumentException if least greater than or equal
181 * to bound
182 */
183 public double nextDouble(double least, double bound) {
184 if (least >= bound)
185 throw new IllegalArgumentException();
186 return nextDouble() * (bound - least) + least;
187 }
188
189 }