ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadLocalRandomTest.java
Revision: 1.20
Committed: Wed Dec 31 19:05:43 2014 UTC (9 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.19: +4 -2 lines
Log Message:
no wildcard imports

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 jsr166 1.8 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.1 */
6 jsr166 1.20
7 jsr166 1.10 import java.util.concurrent.ThreadLocalRandom;
8 jsr166 1.11 import java.util.concurrent.atomic.AtomicLong;
9     import java.util.concurrent.atomic.AtomicReference;
10 dl 1.1
11 jsr166 1.20 import junit.framework.Test;
12     import junit.framework.TestSuite;
13    
14 dl 1.1 public class ThreadLocalRandomTest extends JSR166TestCase {
15    
16     public static void main(String[] args) {
17 jsr166 1.7 junit.textui.TestRunner.run(suite());
18 dl 1.1 }
19     public static Test suite() {
20 jsr166 1.4 return new TestSuite(ThreadLocalRandomTest.class);
21 dl 1.1 }
22    
23 jsr166 1.13 /*
24 dl 1.1 * Testing coverage notes:
25 jsr166 1.2 *
26 dl 1.1 * We don't test randomness properties, but only that repeated
27     * calls, up to NCALLS tries, produce at least one different
28     * result. For bounded versions, we sample various intervals
29     * across multiples of primes.
30     */
31    
32 jsr166 1.14 // max numbers of calls to detect getting stuck on one value
33 dl 1.1 static final int NCALLS = 10000;
34    
35     // max sampled int bound
36     static final int MAX_INT_BOUND = (1 << 28);
37    
38 jsr166 1.14 // max sampled long bound
39 dl 1.1 static final long MAX_LONG_BOUND = (1L << 42);
40    
41 dl 1.15 // Number of replications for other checks
42     static final int REPS = 20;
43    
44 dl 1.1 /**
45     * setSeed throws UnsupportedOperationException
46     */
47     public void testSetSeed() {
48     try {
49     ThreadLocalRandom.current().setSeed(17);
50 jsr166 1.3 shouldThrow();
51 jsr166 1.5 } catch (UnsupportedOperationException success) {}
52 dl 1.1 }
53    
54     /**
55 jsr166 1.14 * Repeated calls to nextInt produce at least two distinct results
56 dl 1.1 */
57     public void testNextInt() {
58     int f = ThreadLocalRandom.current().nextInt();
59     int i = 0;
60     while (i < NCALLS && ThreadLocalRandom.current().nextInt() == f)
61     ++i;
62     assertTrue(i < NCALLS);
63     }
64    
65     /**
66 jsr166 1.14 * Repeated calls to nextLong produce at least two distinct results
67 dl 1.1 */
68     public void testNextLong() {
69     long f = ThreadLocalRandom.current().nextLong();
70     int i = 0;
71     while (i < NCALLS && ThreadLocalRandom.current().nextLong() == f)
72     ++i;
73     assertTrue(i < NCALLS);
74     }
75    
76     /**
77 jsr166 1.14 * Repeated calls to nextBoolean produce at least two distinct results
78 dl 1.1 */
79     public void testNextBoolean() {
80     boolean f = ThreadLocalRandom.current().nextBoolean();
81     int i = 0;
82     while (i < NCALLS && ThreadLocalRandom.current().nextBoolean() == f)
83     ++i;
84     assertTrue(i < NCALLS);
85     }
86    
87     /**
88 jsr166 1.14 * Repeated calls to nextFloat produce at least two distinct results
89 dl 1.1 */
90     public void testNextFloat() {
91     float f = ThreadLocalRandom.current().nextFloat();
92     int i = 0;
93     while (i < NCALLS && ThreadLocalRandom.current().nextFloat() == f)
94     ++i;
95     assertTrue(i < NCALLS);
96     }
97    
98     /**
99 jsr166 1.14 * Repeated calls to nextDouble produce at least two distinct results
100 dl 1.1 */
101     public void testNextDouble() {
102     double f = ThreadLocalRandom.current().nextDouble();
103 jsr166 1.14 int i = 0;
104 dl 1.1 while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f)
105     ++i;
106     assertTrue(i < NCALLS);
107     }
108    
109     /**
110 jsr166 1.14 * Repeated calls to nextGaussian produce at least two distinct results
111 dl 1.1 */
112     public void testNextGaussian() {
113     double f = ThreadLocalRandom.current().nextGaussian();
114     int i = 0;
115     while (i < NCALLS && ThreadLocalRandom.current().nextGaussian() == f)
116     ++i;
117     assertTrue(i < NCALLS);
118     }
119    
120     /**
121 jsr166 1.19 * nextInt(non-positive) throws IllegalArgumentException
122 dl 1.1 */
123 jsr166 1.19 public void testNextIntBoundNonPositive() {
124     ThreadLocalRandom rnd = ThreadLocalRandom.current();
125     for (int bound : new int[] { 0, -17, Integer.MIN_VALUE }) {
126     try {
127     rnd.nextInt(bound);
128     shouldThrow();
129     } catch (IllegalArgumentException success) {}
130     }
131 dl 1.1 }
132    
133     /**
134 jsr166 1.14 * nextInt(least >= bound) throws IllegalArgumentException
135 dl 1.1 */
136     public void testNextIntBadBounds() {
137 jsr166 1.19 int[][] badBoundss = {
138     { 17, 2 },
139     { -42, -42 },
140     { Integer.MAX_VALUE, Integer.MIN_VALUE },
141     };
142     ThreadLocalRandom rnd = ThreadLocalRandom.current();
143     for (int[] badBounds : badBoundss) {
144     try {
145     rnd.nextInt(badBounds[0], badBounds[1]);
146     shouldThrow();
147     } catch (IllegalArgumentException success) {}
148     }
149 dl 1.1 }
150    
151     /**
152     * nextInt(bound) returns 0 <= value < bound;
153 jsr166 1.14 * repeated calls produce at least two distinct results
154 dl 1.1 */
155     public void testNextIntBounded() {
156     // sample bound space across prime number increments
157     for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
158     int f = ThreadLocalRandom.current().nextInt(bound);
159     assertTrue(0 <= f && f < bound);
160     int i = 0;
161     int j;
162 jsr166 1.2 while (i < NCALLS &&
163 dl 1.1 (j = ThreadLocalRandom.current().nextInt(bound)) == f) {
164     assertTrue(0 <= j && j < bound);
165     ++i;
166     }
167     assertTrue(i < NCALLS);
168     }
169     }
170    
171     /**
172     * nextInt(least, bound) returns least <= value < bound;
173 jsr166 1.14 * repeated calls produce at least two distinct results
174 dl 1.1 */
175     public void testNextIntBounded2() {
176     for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
177     for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
178     int f = ThreadLocalRandom.current().nextInt(least, bound);
179     assertTrue(least <= f && f < bound);
180     int i = 0;
181     int j;
182 jsr166 1.2 while (i < NCALLS &&
183 dl 1.1 (j = ThreadLocalRandom.current().nextInt(least, bound)) == f) {
184     assertTrue(least <= j && j < bound);
185     ++i;
186     }
187     assertTrue(i < NCALLS);
188     }
189     }
190     }
191    
192     /**
193 jsr166 1.19 * nextLong(non-positive) throws IllegalArgumentException
194 dl 1.1 */
195 jsr166 1.19 public void testNextLongBoundNonPositive() {
196     ThreadLocalRandom rnd = ThreadLocalRandom.current();
197     for (long bound : new long[] { 0L, -17L, Long.MIN_VALUE }) {
198     try {
199     rnd.nextLong(bound);
200     shouldThrow();
201     } catch (IllegalArgumentException success) {}
202     }
203 dl 1.1 }
204    
205     /**
206 jsr166 1.14 * nextLong(least >= bound) throws IllegalArgumentException
207 dl 1.1 */
208     public void testNextLongBadBounds() {
209 jsr166 1.19 long[][] badBoundss = {
210     { 17L, 2L },
211     { -42L, -42L },
212     { Long.MAX_VALUE, Long.MIN_VALUE },
213     };
214     ThreadLocalRandom rnd = ThreadLocalRandom.current();
215     for (long[] badBounds : badBoundss) {
216     try {
217     rnd.nextLong(badBounds[0], badBounds[1]);
218     shouldThrow();
219     } catch (IllegalArgumentException success) {}
220     }
221 dl 1.1 }
222    
223     /**
224     * nextLong(bound) returns 0 <= value < bound;
225 jsr166 1.14 * repeated calls produce at least two distinct results
226 dl 1.1 */
227     public void testNextLongBounded() {
228     for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
229     long f = ThreadLocalRandom.current().nextLong(bound);
230     assertTrue(0 <= f && f < bound);
231     int i = 0;
232     long j;
233 jsr166 1.2 while (i < NCALLS &&
234 dl 1.1 (j = ThreadLocalRandom.current().nextLong(bound)) == f) {
235     assertTrue(0 <= j && j < bound);
236     ++i;
237     }
238     assertTrue(i < NCALLS);
239     }
240     }
241    
242     /**
243     * nextLong(least, bound) returns least <= value < bound;
244 jsr166 1.14 * repeated calls produce at least two distinct results
245 dl 1.1 */
246     public void testNextLongBounded2() {
247     for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
248     for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
249     long f = ThreadLocalRandom.current().nextLong(least, bound);
250     assertTrue(least <= f && f < bound);
251     int i = 0;
252     long j;
253 jsr166 1.2 while (i < NCALLS &&
254 dl 1.1 (j = ThreadLocalRandom.current().nextLong(least, bound)) == f) {
255     assertTrue(least <= j && j < bound);
256     ++i;
257     }
258     assertTrue(i < NCALLS);
259     }
260     }
261     }
262    
263     /**
264 jsr166 1.19 * nextDouble(non-positive) throws IllegalArgumentException
265     */
266     public void testNextDoubleBoundNonPositive() {
267     ThreadLocalRandom rnd = ThreadLocalRandom.current();
268     double[] badBounds = {
269     0.0d,
270     -17.0d,
271     -Double.MIN_VALUE,
272     Double.NEGATIVE_INFINITY,
273     Double.NaN,
274     };
275     for (double bound : badBounds) {
276     try {
277     rnd.nextDouble(bound);
278     shouldThrow();
279     } catch (IllegalArgumentException success) {}
280     }
281     }
282    
283     /**
284 dl 1.1 * nextDouble(least, bound) returns least <= value < bound;
285 jsr166 1.14 * repeated calls produce at least two distinct results
286 dl 1.1 */
287     public void testNextDoubleBounded2() {
288     for (double least = 0.0001; least < 1.0e20; least *= 8) {
289     for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
290     double f = ThreadLocalRandom.current().nextDouble(least, bound);
291     assertTrue(least <= f && f < bound);
292     int i = 0;
293     double j;
294 jsr166 1.2 while (i < NCALLS &&
295 dl 1.1 (j = ThreadLocalRandom.current().nextDouble(least, bound)) == f) {
296     assertTrue(least <= j && j < bound);
297     ++i;
298     }
299     assertTrue(i < NCALLS);
300     }
301     }
302     }
303    
304 jsr166 1.11 /**
305     * Different threads produce different pseudo-random sequences
306     */
307     public void testDifferentSequences() {
308     // Don't use main thread's ThreadLocalRandom - it is likely to
309     // be polluted by previous tests.
310     final AtomicReference<ThreadLocalRandom> threadLocalRandom =
311     new AtomicReference<ThreadLocalRandom>();
312     final AtomicLong rand = new AtomicLong();
313    
314     long firstRand = 0;
315     ThreadLocalRandom firstThreadLocalRandom = null;
316    
317 jsr166 1.18 Runnable getRandomState = new CheckedRunnable() {
318 jsr166 1.11 public void realRun() {
319     ThreadLocalRandom current = ThreadLocalRandom.current();
320     assertSame(current, ThreadLocalRandom.current());
321 dl 1.12 // test bug: the following is not guaranteed and not true in JDK8
322     // assertNotSame(current, threadLocalRandom.get());
323 jsr166 1.11 rand.set(current.nextLong());
324     threadLocalRandom.set(current);
325     }};
326    
327     Thread first = newStartedThread(getRandomState);
328     awaitTermination(first);
329     firstRand = rand.get();
330     firstThreadLocalRandom = threadLocalRandom.get();
331    
332     for (int i = 0; i < NCALLS; i++) {
333     Thread t = newStartedThread(getRandomState);
334     awaitTermination(t);
335     if (firstRand != rand.get())
336     return;
337     }
338     fail("all threads generate the same pseudo-random sequence");
339     }
340    
341 dl 1.1 }