ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/LockSupportTest.java
Revision: 1.31
Committed: Sat May 13 23:50:00 2017 UTC (6 years, 11 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.30: +7 -8 lines
Log Message:
claw back some millis using assertThreadBlocks

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