ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadLocalRandomTest.java
Revision: 1.16
Committed: Fri Aug 16 07:07:01 2013 UTC (10 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.15: +0 -230 lines
Log Message:
introduce ThreadLocalRandom8Test, fixing 4jdk7-test-tck

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