ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadLocalRandomTest.java
Revision: 1.21
Committed: Sat Apr 25 04:55:31 2015 UTC (9 years ago) by jsr166
Branch: MAIN
Changes since 1.20: +1 -1 lines
Log Message:
improve main methods; respect system properties; actually fail if a test fails

File Contents

# Content
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 import java.util.concurrent.ThreadLocalRandom;
8 import java.util.concurrent.atomic.AtomicLong;
9 import java.util.concurrent.atomic.AtomicReference;
10
11 import junit.framework.Test;
12 import junit.framework.TestSuite;
13
14 public class ThreadLocalRandomTest extends JSR166TestCase {
15
16 public static void main(String[] args) {
17 main(suite(), args);
18 }
19 public static Test suite() {
20 return new TestSuite(ThreadLocalRandomTest.class);
21 }
22
23 /*
24 * Testing coverage notes:
25 *
26 * 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 // max numbers of calls to detect getting stuck on one value
33 static final int NCALLS = 10000;
34
35 // max sampled int bound
36 static final int MAX_INT_BOUND = (1 << 28);
37
38 // max sampled long bound
39 static final long MAX_LONG_BOUND = (1L << 42);
40
41 // Number of replications for other checks
42 static final int REPS = 20;
43
44 /**
45 * setSeed throws UnsupportedOperationException
46 */
47 public void testSetSeed() {
48 try {
49 ThreadLocalRandom.current().setSeed(17);
50 shouldThrow();
51 } catch (UnsupportedOperationException success) {}
52 }
53
54 /**
55 * Repeated calls to nextInt produce at least two distinct results
56 */
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 * Repeated calls to nextLong produce at least two distinct results
67 */
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 * Repeated calls to nextBoolean produce at least two distinct results
78 */
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 * Repeated calls to nextFloat produce at least two distinct results
89 */
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 * Repeated calls to nextDouble produce at least two distinct results
100 */
101 public void testNextDouble() {
102 double f = ThreadLocalRandom.current().nextDouble();
103 int i = 0;
104 while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f)
105 ++i;
106 assertTrue(i < NCALLS);
107 }
108
109 /**
110 * Repeated calls to nextGaussian produce at least two distinct results
111 */
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 * nextInt(non-positive) throws IllegalArgumentException
122 */
123 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 }
132
133 /**
134 * nextInt(least >= bound) throws IllegalArgumentException
135 */
136 public void testNextIntBadBounds() {
137 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 }
150
151 /**
152 * nextInt(bound) returns 0 <= value < bound;
153 * repeated calls produce at least two distinct results
154 */
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 while (i < NCALLS &&
163 (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 * repeated calls produce at least two distinct results
174 */
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 while (i < NCALLS &&
183 (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 * nextLong(non-positive) throws IllegalArgumentException
194 */
195 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 }
204
205 /**
206 * nextLong(least >= bound) throws IllegalArgumentException
207 */
208 public void testNextLongBadBounds() {
209 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 }
222
223 /**
224 * nextLong(bound) returns 0 <= value < bound;
225 * repeated calls produce at least two distinct results
226 */
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 while (i < NCALLS &&
234 (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 * repeated calls produce at least two distinct results
245 */
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 while (i < NCALLS &&
254 (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 * 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 * nextDouble(least, bound) returns least <= value < bound;
285 * repeated calls produce at least two distinct results
286 */
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 while (i < NCALLS &&
295 (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 /**
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 Runnable getRandomState = new CheckedRunnable() {
318 public void realRun() {
319 ThreadLocalRandom current = ThreadLocalRandom.current();
320 assertSame(current, ThreadLocalRandom.current());
321 // test bug: the following is not guaranteed and not true in JDK8
322 // assertNotSame(current, threadLocalRandom.get());
323 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 }