ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ThreadLocalRandom.java
Revision: 1.3
Committed: Wed Aug 19 18:07:36 2009 UTC (14 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.2: +14 -13 lines
Log Message:
sync with jsr166 package

File Contents

# User Rev Content
1 jsr166 1.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 java.util.concurrent;
8    
9     import java.util.Random;
10    
11     /**
12 jsr166 1.3 * A random number generator isolated to the current thread. Like the
13 jsr166 1.2 * global {@link java.util.Random} generator used by the {@link
14 jsr166 1.3 * 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 jsr166 1.1 *
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 jsr166 1.3 * accidently share a {@code ThreadLocalRandom} across multiple threads.
28 jsr166 1.1 *
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 final static long multiplier = 0x5DEECE66DL;
38     private final static long addend = 0xBL;
39     private final static 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 the first and only allowed call
48     * to setSeed (inside Random constructor) to succeed. We can't
49     * allow others since it would cause setting seed in one part of a
50     * program to 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     * We rely on the fact that the superclass no-arg constructor
73     * invokes setSeed exactly once to initialize.
74     */
75     ThreadLocalRandom() {
76     super();
77     }
78    
79     /**
80 jsr166 1.3 * Returns the current thread's {@code ThreadLocalRandom}.
81 jsr166 1.1 *
82 jsr166 1.3 * @return the current thread's {@code ThreadLocalRandom}
83 jsr166 1.1 */
84     public static ThreadLocalRandom current() {
85     return localRandom.get();
86     }
87    
88     /**
89 jsr166 1.3 * Throws {@code UnsupportedOperationException}. Setting seeds in
90     * this generator is not supported.
91 jsr166 1.1 *
92     * @throws UnsupportedOperationException always
93     */
94     public void setSeed(long seed) {
95     if (initialized)
96     throw new UnsupportedOperationException();
97     initialized = true;
98     rnd = (seed ^ multiplier) & mask;
99     }
100    
101     protected int next(int bits) {
102     rnd = (rnd * multiplier + addend) & mask;
103     return (int) (rnd >>> (48-bits));
104     }
105    
106     /**
107     * Returns a pseudorandom, uniformly distributed value between the
108     * given least value (inclusive) and bound (exclusive).
109     *
110     * @param least the least value returned
111     * @param bound the upper bound (exclusive)
112     * @throws IllegalArgumentException if least greater than or equal
113     * to bound
114     * @return the next value
115     */
116     public int nextInt(int least, int bound) {
117     if (least >= bound)
118     throw new IllegalArgumentException();
119     return nextInt(bound - least) + least;
120     }
121    
122     /**
123     * Returns a pseudorandom, uniformly distributed value
124     * between 0 (inclusive) and the specified value (exclusive).
125     *
126     * @param n the bound on the random number to be returned. Must be
127     * positive.
128     * @return the next value
129     * @throws IllegalArgumentException if n is not positive
130     */
131     public long nextLong(long n) {
132     if (n <= 0)
133     throw new IllegalArgumentException("n must be positive");
134     // Divide n by two until small enough for nextInt. On each
135     // iteration (at most 31 of them but usually much less),
136     // randomly choose both whether to include high bit in result
137     // (offset) and whether to continue with the lower vs upper
138     // half (which makes a difference only if odd).
139     long offset = 0;
140     while (n >= Integer.MAX_VALUE) {
141     int bits = next(2);
142     long half = n >>> 1;
143     long nextn = ((bits & 2) == 0) ? half : n - half;
144     if ((bits & 1) == 0)
145     offset += n - nextn;
146     n = nextn;
147     }
148     return offset + nextInt((int) n);
149     }
150    
151     /**
152     * Returns a pseudorandom, uniformly distributed value between the
153     * given least value (inclusive) and bound (exclusive).
154     *
155     * @param least the least value returned
156     * @param bound the upper bound (exclusive)
157     * @return the next value
158     * @throws IllegalArgumentException if least greater than or equal
159     * to bound
160     */
161     public long nextLong(long least, long bound) {
162     if (least >= bound)
163     throw new IllegalArgumentException();
164     return nextLong(bound - least) + least;
165     }
166    
167     /**
168     * Returns a pseudorandom, uniformly distributed {@code double} value
169     * between 0 (inclusive) and the specified value (exclusive).
170     *
171     * @param n the bound on the random number to be returned. Must be
172     * positive.
173     * @return the next value
174     * @throws IllegalArgumentException if n is not positive
175     */
176     public double nextDouble(double n) {
177     if (n <= 0)
178     throw new IllegalArgumentException("n must be positive");
179     return nextDouble() * n;
180     }
181    
182     /**
183     * Returns a pseudorandom, uniformly distributed value between the
184     * given least value (inclusive) and bound (exclusive).
185     *
186     * @param least the least value returned
187     * @param bound the upper bound (exclusive)
188     * @return the next value
189     * @throws IllegalArgumentException if least greater than or equal
190     * to bound
191     */
192     public double nextDouble(double least, double bound) {
193     if (least >= bound)
194     throw new IllegalArgumentException();
195     return nextDouble() * (bound - least) + least;
196     }
197    
198     private static final long serialVersionUID = -5851777807851030925L;
199     }