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

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