ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/LockSupportTest.java
Revision: 1.23
Committed: Sat May 28 22:21:58 2011 UTC (12 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.22: +255 -246 lines
Log Message:
test blocker methods; extreme refactor

File Contents

# Content
1 /*
2 * Written by Doug Lea and Martin Buchholz with assistance from
3 * members of JCP JSR-166 Expert Group and released to the public
4 * domain, as explained at
5 * http://creativecommons.org/publicdomain/zero/1.0/
6 * Other contributors include Andrew Wright, Jeffrey Hayes,
7 * Pat Fisher, Mike Judd.
8 */
9
10 import junit.framework.*;
11 import java.util.concurrent.CountDownLatch;
12 import java.util.concurrent.atomic.AtomicBoolean;
13 import java.util.concurrent.locks.LockSupport;
14 import static java.util.concurrent.TimeUnit.MILLISECONDS;
15
16 public class LockSupportTest extends JSR166TestCase {
17 public static void main(String[] args) {
18 junit.textui.TestRunner.run(suite());
19 }
20
21 public static Test suite() {
22 return new TestSuite(LockSupportTest.class);
23 }
24
25 /**
26 * Returns the blocker object used by tests in this file.
27 * Any old object will do; we'll return a convenient one.
28 */
29 static Object theBlocker() {
30 return LockSupportTest.class;
31 }
32
33 enum ParkMethod {
34 park() {
35 void park() {
36 LockSupport.park();
37 }
38 void park(long millis) {
39 throw new UnsupportedOperationException();
40 }
41 },
42 parkUntil() {
43 void park(long millis) {
44 LockSupport.parkUntil(deadline(millis));
45 }
46 },
47 parkNanos() {
48 void park(long millis) {
49 LockSupport.parkNanos(MILLISECONDS.toNanos(millis));
50 }
51 },
52 parkBlocker() {
53 void park() {
54 LockSupport.park(theBlocker());
55 }
56 void park(long millis) {
57 throw new UnsupportedOperationException();
58 }
59 },
60 parkUntilBlocker() {
61 void park(long millis) {
62 LockSupport.parkUntil(theBlocker(), deadline(millis));
63 }
64 },
65 parkNanosBlocker() {
66 void park(long millis) {
67 LockSupport.parkNanos(theBlocker(),
68 MILLISECONDS.toNanos(millis));
69 }
70 };
71
72 void park() { park(2 * LONG_DELAY_MS); }
73 abstract void park(long millis);
74
75 /** Returns a deadline to use with parkUntil. */
76 long deadline(long millis) {
77 // beware of rounding
78 return System.currentTimeMillis() + millis + 1;
79 }
80 }
81
82 /**
83 * park is released by subsequent unpark
84 */
85 public void testParkBeforeUnpark_park() {
86 testParkBeforeUnpark(ParkMethod.park);
87 }
88 public void testParkBeforeUnpark_parkNanos() {
89 testParkBeforeUnpark(ParkMethod.parkNanos);
90 }
91 public void testParkBeforeUnpark_parkUntil() {
92 testParkBeforeUnpark(ParkMethod.parkUntil);
93 }
94 public void testParkBeforeUnpark_parkBlocker() {
95 testParkBeforeUnpark(ParkMethod.parkBlocker);
96 }
97 public void testParkBeforeUnpark_parkNanosBlocker() {
98 testParkBeforeUnpark(ParkMethod.parkNanosBlocker);
99 }
100 public void testParkBeforeUnpark_parkUntilBlocker() {
101 testParkBeforeUnpark(ParkMethod.parkUntilBlocker);
102 }
103 public void testParkBeforeUnpark(final ParkMethod parkMethod) {
104 final CountDownLatch pleaseUnpark = new CountDownLatch(1);
105 Thread t = newStartedThread(new CheckedRunnable() {
106 public void realRun() {
107 pleaseUnpark.countDown();
108 parkMethod.park();
109 }});
110
111 await(pleaseUnpark);
112 LockSupport.unpark(t);
113 awaitTermination(t);
114 }
115
116 /**
117 * park is released by preceding unpark
118 */
119 public void testParkAfterUnpark_park() {
120 testParkAfterUnpark(ParkMethod.park);
121 }
122 public void testParkAfterUnpark_parkNanos() {
123 testParkAfterUnpark(ParkMethod.parkNanos);
124 }
125 public void testParkAfterUnpark_parkUntil() {
126 testParkAfterUnpark(ParkMethod.parkUntil);
127 }
128 public void testParkAfterUnpark_parkBlocker() {
129 testParkAfterUnpark(ParkMethod.parkBlocker);
130 }
131 public void testParkAfterUnpark_parkNanosBlocker() {
132 testParkAfterUnpark(ParkMethod.parkNanosBlocker);
133 }
134 public void testParkAfterUnpark_parkUntilBlocker() {
135 testParkAfterUnpark(ParkMethod.parkUntilBlocker);
136 }
137 public void testParkAfterUnpark(final ParkMethod parkMethod) {
138 final CountDownLatch pleaseUnpark = new CountDownLatch(1);
139 final AtomicBoolean pleasePark = new AtomicBoolean(false);
140 Thread t = newStartedThread(new CheckedRunnable() {
141 public void realRun() {
142 pleaseUnpark.countDown();
143 while (!pleasePark.get())
144 Thread.yield();
145 parkMethod.park();
146 }});
147
148 await(pleaseUnpark);
149 LockSupport.unpark(t);
150 pleasePark.set(true);
151 awaitTermination(t);
152 }
153
154 /**
155 * park is released by subsequent interrupt
156 */
157 public void testParkBeforeInterrupt_park() {
158 testParkBeforeInterrupt(ParkMethod.park);
159 }
160 public void testParkBeforeInterrupt_parkNanos() {
161 testParkBeforeInterrupt(ParkMethod.parkNanos);
162 }
163 public void testParkBeforeInterrupt_parkUntil() {
164 testParkBeforeInterrupt(ParkMethod.parkUntil);
165 }
166 public void testParkBeforeInterrupt_parkBlocker() {
167 testParkBeforeInterrupt(ParkMethod.parkBlocker);
168 }
169 public void testParkBeforeInterrupt_parkNanosBlocker() {
170 testParkBeforeInterrupt(ParkMethod.parkNanosBlocker);
171 }
172 public void testParkBeforeInterrupt_parkUntilBlocker() {
173 testParkBeforeInterrupt(ParkMethod.parkUntilBlocker);
174 }
175 public void testParkBeforeInterrupt(final ParkMethod parkMethod) {
176 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
177 Thread t = newStartedThread(new CheckedRunnable() {
178 public void realRun() {
179 pleaseInterrupt.countDown();
180 do {
181 parkMethod.park();
182 // park may return spuriously
183 } while (! Thread.currentThread().isInterrupted());
184 }});
185
186 await(pleaseInterrupt);
187 assertThreadStaysAlive(t);
188 t.interrupt();
189 awaitTermination(t);
190 }
191
192 /**
193 * park is released by preceding interrupt
194 */
195 public void testParkAfterInterrupt_park() {
196 testParkAfterInterrupt(ParkMethod.park);
197 }
198 public void testParkAfterInterrupt_parkNanos() {
199 testParkAfterInterrupt(ParkMethod.parkNanos);
200 }
201 public void testParkAfterInterrupt_parkUntil() {
202 testParkAfterInterrupt(ParkMethod.parkUntil);
203 }
204 public void testParkAfterInterrupt_parkBlocker() {
205 testParkAfterInterrupt(ParkMethod.parkBlocker);
206 }
207 public void testParkAfterInterrupt_parkNanosBlocker() {
208 testParkAfterInterrupt(ParkMethod.parkNanosBlocker);
209 }
210 public void testParkAfterInterrupt_parkUntilBlocker() {
211 testParkAfterInterrupt(ParkMethod.parkUntilBlocker);
212 }
213 public void testParkAfterInterrupt(final ParkMethod parkMethod) {
214 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
215 final AtomicBoolean pleasePark = new AtomicBoolean(false);
216 Thread t = newStartedThread(new CheckedRunnable() {
217 public void realRun() throws Exception {
218 pleaseInterrupt.countDown();
219 while (!pleasePark.get())
220 Thread.yield();
221 assertTrue(Thread.currentThread().isInterrupted());
222 parkMethod.park();
223 assertTrue(Thread.currentThread().isInterrupted());
224 }});
225
226 await(pleaseInterrupt);
227 t.interrupt();
228 pleasePark.set(true);
229 awaitTermination(t);
230 }
231
232 /**
233 * timed park times out if not unparked
234 */
235 public void testParkTimesOut_parkNanos() {
236 testParkTimesOut(ParkMethod.parkNanos);
237 }
238 public void testParkTimesOut_parkUntil() {
239 testParkTimesOut(ParkMethod.parkUntil);
240 }
241 public void testParkTimesOut_parkNanosBlocker() {
242 testParkTimesOut(ParkMethod.parkNanosBlocker);
243 }
244 public void testParkTimesOut_parkUntilBlocker() {
245 testParkTimesOut(ParkMethod.parkUntilBlocker);
246 }
247 public void testParkTimesOut(final ParkMethod parkMethod) {
248 Thread t = newStartedThread(new CheckedRunnable() {
249 public void realRun() {
250 for (;;) {
251 long startTime = System.nanoTime();
252 parkMethod.park(timeoutMillis());
253 // park may return spuriously
254 if (millisElapsedSince(startTime) >= timeoutMillis())
255 return;
256 }
257 }});
258
259 awaitTermination(t);
260 }
261
262 /**
263 * getBlocker(null) throws NullPointerException
264 */
265 public void testGetBlockerNull() {
266 try {
267 LockSupport.getBlocker(null);
268 shouldThrow();
269 } catch (NullPointerException success) {}
270 }
271
272 /**
273 * getBlocker returns the blocker object passed to park
274 */
275 public void testGetBlocker_parkBlocker() {
276 testGetBlocker(ParkMethod.parkBlocker);
277 }
278 public void testGetBlocker_parkNanosBlocker() {
279 testGetBlocker(ParkMethod.parkNanosBlocker);
280 }
281 public void testGetBlocker_parkUntilBlocker() {
282 testGetBlocker(ParkMethod.parkUntilBlocker);
283 }
284 public void testGetBlocker(final ParkMethod parkMethod) {
285 final CountDownLatch started = new CountDownLatch(1);
286 Thread t = newStartedThread(new CheckedRunnable() {
287 public void realRun() {
288 Thread t = Thread.currentThread();
289 started.countDown();
290 do {
291 assertNull(LockSupport.getBlocker(t));
292 parkMethod.park();
293 assertNull(LockSupport.getBlocker(t));
294 // park may return spuriously
295 } while (! Thread.currentThread().isInterrupted());
296 }});
297
298 long startTime = System.nanoTime();
299 await(started);
300 for (;;) {
301 Object x = LockSupport.getBlocker(t);
302 if (x == theBlocker()) { // success
303 t.interrupt();
304 awaitTermination(t);
305 assertNull(LockSupport.getBlocker(t));
306 return;
307 } else {
308 assertNull(x); // ok
309 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
310 fail("timed out");
311 Thread.yield();
312 }
313 }
314 }
315
316 /**
317 * timed park(0) returns immediately.
318 *
319 * Requires hotspot fix for:
320 * 6763959 java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
321 * which is in jdk7-b118 and 6u25.
322 */
323 public void testPark0_parkNanos() {
324 testPark0(ParkMethod.parkNanos);
325 }
326 public void testPark0_parkUntil() {
327 testPark0(ParkMethod.parkUntil);
328 }
329 public void testPark0_parkNanosBlocker() {
330 testPark0(ParkMethod.parkNanosBlocker);
331 }
332 public void testPark0_parkUntilBlocker() {
333 testPark0(ParkMethod.parkUntilBlocker);
334 }
335 public void testPark0(final ParkMethod parkMethod) {
336 Thread t = newStartedThread(new CheckedRunnable() {
337 public void realRun() {
338 parkMethod.park(0L);
339 }});
340
341 awaitTermination(t);
342 }
343
344 /**
345 * timed park(Long.MIN_VALUE) returns immediately.
346 */
347 public void testParkNeg_parkNanos() {
348 testParkNeg(ParkMethod.parkNanos);
349 }
350 public void testParkNeg_parkUntil() {
351 testParkNeg(ParkMethod.parkUntil);
352 }
353 public void testParkNeg_parkNanosBlocker() {
354 testParkNeg(ParkMethod.parkNanosBlocker);
355 }
356 public void testParkNeg_parkUntilBlocker() {
357 testParkNeg(ParkMethod.parkUntilBlocker);
358 }
359 public void testParkNeg(final ParkMethod parkMethod) {
360 Thread t = newStartedThread(new CheckedRunnable() {
361 public void realRun() {
362 parkMethod.park(Long.MIN_VALUE);
363 }});
364
365 awaitTermination(t);
366 }
367 }