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

# 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 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     * The random seed. We can't use super.seed
42     */
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 dl 1.1 * @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 jsr166 1.3 * @throws UnsupportedOperationException always
90 dl 1.1 */
91 jsr166 1.3 public void setSeed(long seed) {
92 dl 1.1 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 dl 1.2 // 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 jsr166 1.3 // half (which makes a difference only if odd).
133 dl 1.1 long offset = 0;
134 dl 1.2 while (n >= Integer.MAX_VALUE) {
135 jsr166 1.3 int bits = next(2);
136 dl 1.1 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 jsr166 1.7 return offset + nextInt((int) n);
143 dl 1.1 }
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 jsr166 1.3 }