ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/LockSupportTest.java
Revision: 1.30
Committed: Fri May 12 18:57:11 2017 UTC (7 years ago) by jsr166
Branch: MAIN
Changes since 1.29: +2 -5 lines
Log Message:
testParkAfterInterrupt: eliminate pleasePark

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