ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/ThreadLocalRandom.java
Revision: 1.1
Committed: Mon Jan 12 17:16:18 2009 UTC (15 years, 4 months ago) by dl
Branch: MAIN
Log Message:
Split out ThreadLocalRandom; internal refactoring pass

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     * A Random number generator with the same properties as {@link
12     * Random} but isolated to the current Thread. Like the global
13     * generator used by {@link java.lang.Math}, a ThreadLocalRandom is
14     * initialized with an internally generated seed that may not
15     * otherwise be modified. When applicable, use of ThreadLocalRandom
16     * rather than shared Random objects in concurrent programs will
17     * typically encounter less overhead and contention. The most common
18     * usage form is: <code>ThreadLocalRandom.current().nextX()</code>.
19     *
20     * <p>This class also provides additional commonly used bounded random
21     * generation methods.
22     */
23     public class ThreadLocalRandom extends Random {
24     // same constants as Random, but must be redeclared because private
25     private final static long multiplier = 0x5DEECE66DL;
26     private final static long addend = 0xBL;
27     private final static long mask = (1L << 48) - 1;
28    
29     /**
30     * The random seed. We can't use super.seed
31     */
32     private long rnd;
33    
34     /**
35     * Initialization flag to permit the first and only allowed call
36     * to setSeed (inside Random constructor) to succeed. We can't
37     * allow others since it would cause setting seed in one part of a
38     * program to inintentionally impact other usages by the thread.
39     */
40     boolean initialized;
41    
42     // Padding to help avoid memory contention among seed updates in
43     // different TLRs in the common case that they are located near
44     // each other.
45     private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
46    
47     private static final ThreadLocal<ThreadLocalRandom> localRandom =
48     new ThreadLocal<ThreadLocalRandom>() {
49     protected ThreadLocalRandom initialValue() {
50     return new ThreadLocalRandom();
51     }
52     };
53    
54     ThreadLocalRandom() { // construct only in localRandom.initialValue
55     super(); // super constructor calls setSeed
56     }
57    
58     /**
59     * Returns the current Thread's ThreadLocalRandom
60     * @return the current Thread's ThreadLocalRandom
61     */
62     public static ThreadLocalRandom current() {
63     return localRandom.get();
64     }
65    
66     /**
67     * Throws UnsupportedOperationException. Setting seeds in this
68     * generator is unsupported.
69     * @throw UnsupportedOperationException always
70     */
71     public void setSeed(long seed) {
72     if (initialized)
73     throw new UnsupportedOperationException();
74     initialized = true;
75     rnd = (seed ^ multiplier) & mask;
76     }
77    
78     protected int next(int bits) {
79     return (int)((rnd = (rnd * multiplier + addend) & mask) >>> (48-bits));
80     }
81    
82     /**
83     * Returns a pseudorandom, uniformly distributed value between the
84     * given least value (inclusive) and bound (exclusive).
85     * @param least the least value returned
86     * @param bound the upper bound (exclusive)
87     * @throws IllegalArgumentException if least greater than or equal
88     * to bound
89     * @return the next value
90     */
91     public int nextInt(int least, int bound) {
92     if (least >= bound)
93     throw new IllegalArgumentException();
94     return nextInt(bound - least) + least;
95     }
96    
97     /**
98     * Returns a pseudorandom, uniformly distributed value
99     * between 0 (inclusive) and the specified value (exclusive)
100     * @param n the bound on the random number to be returned. Must be
101     * positive.
102     * @return the next value
103     * @throws IllegalArgumentException if n is not positive
104     */
105     public long nextLong(long n) {
106     if (n <= 0)
107     throw new IllegalArgumentException("n must be positive");
108     long offset = 0;
109     while (n >= Integer.MAX_VALUE) { // randomly pick half range
110     int bits = next(2); // 2nd bit for odd vs even split
111     long half = n >>> 1;
112     long nextn = ((bits & 2) == 0)? half : n - half;
113     if ((bits & 1) == 0)
114     offset += n - nextn;
115     n = nextn;
116     }
117     return offset + nextInt((int)n);
118     }
119    
120     /**
121     * Returns a pseudorandom, uniformly distributed value between the
122     * given least value (inclusive) and bound (exclusive).
123     * @param least the least value returned
124     * @param bound the upper bound (exclusive)
125     * @return the next value
126     * @throws IllegalArgumentException if least greater than or equal
127     * to bound
128     */
129     public long nextLong(long least, long bound) {
130     if (least >= bound)
131     throw new IllegalArgumentException();
132     return nextLong(bound - least) + least;
133     }
134    
135     /**
136     * Returns a pseudorandom, uniformly distributed {@code double} value
137     * between 0 (inclusive) and the specified value (exclusive)
138     * @param n the bound on the random number to be returned. Must be
139     * positive.
140     * @return the next value
141     * @throws IllegalArgumentException if n is not positive
142     */
143     public double nextDouble(double n) {
144     if (n <= 0)
145     throw new IllegalArgumentException("n must be positive");
146     return nextDouble() * n;
147     }
148    
149     /**
150     * Returns a pseudorandom, uniformly distributed value between the
151     * given least value (inclusive) and bound (exclusive).
152     * @param least the least value returned
153     * @param bound the upper bound (exclusive)
154     * @return the next value
155     * @throws IllegalArgumentException if least greater than or equal
156     * to bound
157     */
158     public double nextDouble(double least, double bound) {
159     if (least >= bound)
160     throw new IllegalArgumentException();
161     return nextDouble() * (bound - least) + least;
162     }
163    
164     }