ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/ThreadLocalRandom.java
Revision: 1.5
Committed: Tue Jul 21 00:15:14 2009 UTC (14 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.4: +1 -1 lines
Log Message:
j.u.c. coding standards

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