ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/ThreadLocalRandom.java
Revision: 1.11
Committed: Fri Jul 31 16:25:20 2009 UTC (14 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.10: +9 -10 lines
Log Message:
Clarify spec

File Contents

# User Rev Content
1 dl 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 jsr166y;
8 jsr166 1.10
9     import java.util.Random;
10 dl 1.1
11     /**
12 dl 1.11 * 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 ThreadLocalRandom is initialized with an
15     * internally generated seed that may not otherwise be modified. When
16     * applicable, use of ThreadLocalRandom rather than shared Random
17     * objects in concurrent programs will typically encounter much less
18     * overhead and contention. ThreadLocalRandoms are particularly
19     * appropriate when multiple tasks (for example, each a {@link
20     * ForkJoinTask}), use random numbers in parallel in thread pools.
21 jsr166 1.3 *
22 dl 1.2 * <p>Usages of this class should typically be of the form:
23 jsr166 1.4 * {@code ThreadLocalRandom.current().nextX(...)} (where
24     * {@code X} is {@code Int}, {@code Long}, etc).
25 dl 1.2 * When all usages are of this form, it is never possible to
26     * accidently share ThreadLocalRandoms across multiple threads.
27 dl 1.1 *
28     * <p>This class also provides additional commonly used bounded random
29     * generation methods.
30 jsr166 1.6 *
31     * @since 1.7
32     * @author Doug Lea
33 dl 1.1 */
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 jsr166 1.8 * The random seed. We can't use super.seed.
42 dl 1.1 */
43 jsr166 1.3 private long rnd;
44 dl 1.1
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 dl 1.2 * program to unintentionally impact other usages by the thread.
50 dl 1.1 */
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 dl 1.2 /**
59     * The actual ThreadLocal
60     */
61 dl 1.1 private static final ThreadLocal<ThreadLocalRandom> localRandom =
62     new ThreadLocal<ThreadLocalRandom>() {
63     protected ThreadLocalRandom initialValue() {
64     return new ThreadLocalRandom();
65     }
66     };
67    
68 dl 1.2
69     /**
70     * Constructor called only by localRandom.initialValue.
71 jsr166 1.3 * We rely on the fact that the superclass no-arg constructor
72 dl 1.2 * invokes setSeed exactly once to initialize.
73     */
74     ThreadLocalRandom() {
75     super();
76 dl 1.1 }
77    
78     /**
79 jsr166 1.5 * Returns the current Thread's ThreadLocalRandom.
80 jsr166 1.8 *
81 dl 1.1 * @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 jsr166 1.8 *
91 jsr166 1.3 * @throws UnsupportedOperationException always
92 dl 1.1 */
93 jsr166 1.3 public void setSeed(long seed) {
94 dl 1.1 if (initialized)
95     throw new UnsupportedOperationException();
96     initialized = true;
97     rnd = (seed ^ multiplier) & mask;
98     }
99    
100     protected int next(int bits) {
101 jsr166 1.8 rnd = (rnd * multiplier + addend) & mask;
102     return (int) (rnd >>> (48-bits));
103 dl 1.1 }
104    
105     /**
106     * Returns a pseudorandom, uniformly distributed value between the
107     * given least value (inclusive) and bound (exclusive).
108 jsr166 1.8 *
109 dl 1.1 * @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 jsr166 1.8 * between 0 (inclusive) and the specified value (exclusive).
124     *
125 dl 1.1 * @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 dl 1.2 // 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 jsr166 1.3 // half (which makes a difference only if odd).
138 dl 1.1 long offset = 0;
139 dl 1.2 while (n >= Integer.MAX_VALUE) {
140 jsr166 1.3 int bits = next(2);
141 dl 1.1 long half = n >>> 1;
142 jsr166 1.8 long nextn = ((bits & 2) == 0) ? half : n - half;
143 dl 1.1 if ((bits & 1) == 0)
144     offset += n - nextn;
145     n = nextn;
146     }
147 jsr166 1.7 return offset + nextInt((int) n);
148 dl 1.1 }
149    
150     /**
151     * Returns a pseudorandom, uniformly distributed value between the
152     * given least value (inclusive) and bound (exclusive).
153 jsr166 1.8 *
154 dl 1.1 * @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 jsr166 1.8 * between 0 (inclusive) and the specified value (exclusive).
169     *
170 dl 1.1 * @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 jsr166 1.8 *
185 dl 1.1 * @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 jsr166 1.9 private static final long serialVersionUID = -5851777807851030925L;
198 jsr166 1.3 }