ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/ThreadLocalRandom.java
Revision: 1.1
Committed: Sun Jul 14 19:55:05 2013 UTC (10 years, 10 months ago) by jsr166
Branch: MAIN
Log Message:
backport jsr166e to run on jdk6; backport all applicable tck tests from tck to tck-jsr166e

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