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

# User Rev Content
1 dl 1.1 /*
2 jsr166 1.15 * 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 jsr166 1.18 * http://creativecommons.org/publicdomain/zero/1.0/
6 jsr166 1.8 * Other contributors include Andrew Wright, Jeffrey Hayes,
7     * Pat Fisher, Mike Judd.
8 dl 1.1 */
9    
10 jsr166 1.24 import static java.util.concurrent.TimeUnit.MILLISECONDS;
11    
12 jsr166 1.23 import java.util.concurrent.CountDownLatch;
13 jsr166 1.15 import java.util.concurrent.atomic.AtomicBoolean;
14 jsr166 1.23 import java.util.concurrent.locks.LockSupport;
15 jsr166 1.24
16     import junit.framework.Test;
17     import junit.framework.TestSuite;
18 dl 1.1
19 jsr166 1.10 public class LockSupportTest extends JSR166TestCase {
20 dl 1.1 public static void main(String[] args) {
21 jsr166 1.25 main(suite(), args);
22 dl 1.1 }
23 jsr166 1.15
24 dl 1.1 public static Test suite() {
25 jsr166 1.12 return new TestSuite(LockSupportTest.class);
26 dl 1.1 }
27    
28 jsr166 1.26 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 dl 1.3 /**
35 jsr166 1.23 * Returns the blocker object used by tests in this file.
36     * Any old object will do; we'll return a convenient one.
37 dl 1.3 */
38 jsr166 1.23 static Object theBlocker() {
39     return LockSupportTest.class;
40     }
41    
42     enum ParkMethod {
43     park() {
44     void park() {
45 jsr166 1.11 LockSupport.park();
46 jsr166 1.23 }
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 jsr166 1.15 }
90    
91     /**
92 jsr166 1.23 * park is released by subsequent unpark
93 jsr166 1.15 */
94 jsr166 1.23 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 jsr166 1.15 }
112 jsr166 1.23 public void testParkBeforeUnpark(final ParkMethod parkMethod) {
113     final CountDownLatch pleaseUnpark = new CountDownLatch(1);
114 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
115 jsr166 1.15 public void realRun() {
116 jsr166 1.23 pleaseUnpark.countDown();
117     parkMethod.park();
118 jsr166 1.15 }});
119    
120 jsr166 1.23 await(pleaseUnpark);
121 jsr166 1.11 LockSupport.unpark(t);
122 jsr166 1.23 awaitTermination(t);
123 dl 1.1 }
124    
125 dl 1.3 /**
126 jsr166 1.15 * park is released by preceding unpark
127 dl 1.4 */
128 jsr166 1.23 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 dl 1.4 }
143 jsr166 1.23 public void testParkAfterUnpark_parkUntilBlocker() {
144     testParkAfterUnpark(ParkMethod.parkUntilBlocker);
145 jsr166 1.15 }
146 jsr166 1.23 public void testParkAfterUnpark(final ParkMethod parkMethod) {
147     final CountDownLatch pleaseUnpark = new CountDownLatch(1);
148     final AtomicBoolean pleasePark = new AtomicBoolean(false);
149 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
150 jsr166 1.23 public void realRun() {
151     pleaseUnpark.countDown();
152     while (!pleasePark.get())
153 jsr166 1.15 Thread.yield();
154 jsr166 1.23 parkMethod.park();
155 jsr166 1.15 }});
156    
157 jsr166 1.23 await(pleaseUnpark);
158 jsr166 1.15 LockSupport.unpark(t);
159 jsr166 1.23 pleasePark.set(true);
160     awaitTermination(t);
161 jsr166 1.15 }
162    
163     /**
164     * park is released by subsequent interrupt
165     */
166 jsr166 1.23 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 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
187 jsr166 1.12 public void realRun() {
188 jsr166 1.23 pleaseInterrupt.countDown();
189 jsr166 1.29 for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
190 jsr166 1.23 parkMethod.park();
191 jsr166 1.29 if (Thread.interrupted())
192     return;
193     }
194     fail("too many consecutive spurious wakeups?");
195 jsr166 1.15 }});
196    
197 jsr166 1.23 await(pleaseInterrupt);
198     assertThreadStaysAlive(t);
199 jsr166 1.15 t.interrupt();
200 jsr166 1.23 awaitTermination(t);
201 jsr166 1.15 }
202    
203     /**
204 jsr166 1.23 * park is released by preceding interrupt
205 jsr166 1.15 */
206 jsr166 1.23 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 dl 1.4 }
221 jsr166 1.23 public void testParkAfterInterrupt_parkUntilBlocker() {
222     testParkAfterInterrupt(ParkMethod.parkUntilBlocker);
223 jsr166 1.15 }
224 jsr166 1.23 public void testParkAfterInterrupt(final ParkMethod parkMethod) {
225     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
226 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
227 jsr166 1.15 public void realRun() throws Exception {
228 jsr166 1.23 pleaseInterrupt.countDown();
229 jsr166 1.30 while (!Thread.currentThread().isInterrupted())
230 jsr166 1.15 Thread.yield();
231 jsr166 1.23 parkMethod.park();
232 jsr166 1.30 assertTrue(Thread.interrupted());
233 jsr166 1.15 }});
234    
235 jsr166 1.23 await(pleaseInterrupt);
236 jsr166 1.15 t.interrupt();
237 jsr166 1.23 awaitTermination(t);
238 jsr166 1.15 }
239    
240     /**
241 jsr166 1.23 * timed park times out if not unparked
242 jsr166 1.15 */
243 jsr166 1.23 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 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
257 jsr166 1.23 public void realRun() {
258 jsr166 1.27 for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
259 jsr166 1.23 long startTime = System.nanoTime();
260     parkMethod.park(timeoutMillis());
261     if (millisElapsedSince(startTime) >= timeoutMillis())
262     return;
263     }
264 jsr166 1.27 fail("too many consecutive spurious wakeups?");
265 jsr166 1.15 }});
266    
267 jsr166 1.23 awaitTermination(t);
268 jsr166 1.15 }
269    
270     /**
271 jsr166 1.23 * getBlocker(null) throws NullPointerException
272 jsr166 1.15 */
273 jsr166 1.23 public void testGetBlockerNull() {
274     try {
275     LockSupport.getBlocker(null);
276     shouldThrow();
277     } catch (NullPointerException success) {}
278 dl 1.4 }
279    
280     /**
281 jsr166 1.23 * getBlocker returns the blocker object passed to park
282 dl 1.3 */
283 jsr166 1.23 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 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
295 jsr166 1.12 public void realRun() {
296 jsr166 1.23 Thread t = Thread.currentThread();
297     started.countDown();
298 jsr166 1.29 for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
299 jsr166 1.23 assertNull(LockSupport.getBlocker(t));
300     parkMethod.park();
301     assertNull(LockSupport.getBlocker(t));
302 jsr166 1.29 if (Thread.interrupted())
303     return;
304     }
305     fail("too many consecutive spurious wakeups?");
306 jsr166 1.11 }});
307    
308 jsr166 1.23 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 jsr166 1.29 if (t.getState() == Thread.State.TERMINATED)
322     break;
323 jsr166 1.23 Thread.yield();
324     }
325     }
326 dl 1.1 }
327    
328 dl 1.3 /**
329 jsr166 1.23 * 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 dl 1.3 */
335 jsr166 1.23 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 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
349 jsr166 1.12 public void realRun() {
350 jsr166 1.23 parkMethod.park(0L);
351 jsr166 1.15 }});
352    
353 jsr166 1.23 awaitTermination(t);
354 jsr166 1.15 }
355    
356     /**
357 jsr166 1.23 * timed park(Long.MIN_VALUE) returns immediately.
358 jsr166 1.20 */
359 jsr166 1.23 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 jsr166 1.20 }
371 jsr166 1.23 public void testParkNeg(final ParkMethod parkMethod) {
372 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
373 jsr166 1.15 public void realRun() {
374 jsr166 1.23 parkMethod.park(Long.MIN_VALUE);
375 jsr166 1.11 }});
376    
377 jsr166 1.21 awaitTermination(t);
378 dl 1.1 }
379     }