ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/LockSupportTest.java
(Generate patch)

Comparing jsr166/src/test/tck/LockSupportTest.java (file contents):
Revision 1.1 by dl, Sun Aug 31 19:24:55 2003 UTC vs.
Revision 1.28 by jsr166, Fri May 12 18:23:11 2017 UTC

# Line 1 | Line 1
1   /*
2 < * Written by members of JCP JSR-166 Expert Group and released to the
3 < * public domain. Use, modify, and redistribute this code in any way
4 < * without acknowledgement. Other contributors include Andrew Wright,
5 < * Jeffrey Hayes, Pat Fischer, Mike Judd.
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.*;
9 < import java.util.*;
10 < import java.util.concurrent.*;
11 < import java.util.concurrent.locks.*;
10 > import static java.util.concurrent.TimeUnit.MILLISECONDS;
11  
12 < public class LockSupportTest extends TestCase{
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 <        junit.textui.TestRunner.run (suite());  
21 >        main(suite(), args);
22      }
18    
23  
24      public static Test suite() {
25 <        return new TestSuite(LockSupportTest.class);
25 >        return new TestSuite(LockSupportTest.class);
26      }
27  
28 <    public void testUnpark() {
29 <        Thread t = new Thread(new Runnable(){
30 <                public void run(){
31 <                    try{
28 <                        LockSupport.park();
29 <                    }catch(Exception e){
30 <                        fail("unexpected exception");
31 <                    }
32 <                }
33 <            });
34 <        t.start();
35 <        try{
36 <            LockSupport.unpark(t);
37 <            t.join();
38 <        }
39 <        catch(Exception e) {
40 <            fail("unexpected exception");
41 <        }
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 <    public void testParkNanos() {
35 <        Thread t = new Thread(new Runnable(){
36 <                public void run(){
37 <                    try{
38 <                        LockSupport.parkNanos(1000);
39 <                    }catch(Exception e){
40 <                        fail("unexpected exception");
41 <                    }
42 <                }
43 <            });
44 <        try{
45 <            t.start();
46 <            t.join();
47 <        }
48 <        catch(Exception e) {
49 <            fail("unexpected exception");
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 +                do {
190 +                    parkMethod.park();
191 +                    // park may return spuriously
192 +                } while (! Thread.interrupted());
193 +            }});
194 +
195 +        await(pleaseInterrupt);
196 +        assertThreadStaysAlive(t);
197 +        t.interrupt();
198 +        awaitTermination(t);
199 +    }
200 +
201 +    /**
202 +     * park is released by preceding interrupt
203 +     */
204 +    public void testParkAfterInterrupt_park() {
205 +        testParkAfterInterrupt(ParkMethod.park);
206 +    }
207 +    public void testParkAfterInterrupt_parkNanos() {
208 +        testParkAfterInterrupt(ParkMethod.parkNanos);
209 +    }
210 +    public void testParkAfterInterrupt_parkUntil() {
211 +        testParkAfterInterrupt(ParkMethod.parkUntil);
212 +    }
213 +    public void testParkAfterInterrupt_parkBlocker() {
214 +        testParkAfterInterrupt(ParkMethod.parkBlocker);
215 +    }
216 +    public void testParkAfterInterrupt_parkNanosBlocker() {
217 +        testParkAfterInterrupt(ParkMethod.parkNanosBlocker);
218 +    }
219 +    public void testParkAfterInterrupt_parkUntilBlocker() {
220 +        testParkAfterInterrupt(ParkMethod.parkUntilBlocker);
221 +    }
222 +    public void testParkAfterInterrupt(final ParkMethod parkMethod) {
223 +        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
224 +        final AtomicBoolean pleasePark = new AtomicBoolean(false);
225 +        Thread t = newStartedThread(new CheckedRunnable() {
226 +            public void realRun() throws Exception {
227 +                pleaseInterrupt.countDown();
228 +                while (!pleasePark.get())
229 +                    Thread.yield();
230 +                assertTrue(Thread.currentThread().isInterrupted());
231 +                parkMethod.park();
232 +                assertTrue(Thread.currentThread().isInterrupted());
233 +            }});
234 +
235 +        await(pleaseInterrupt);
236 +        t.interrupt();
237 +        pleasePark.set(true);
238 +        awaitTermination(t);
239 +    }
240 +
241 +    /**
242 +     * timed park times out if not unparked
243 +     */
244 +    public void testParkTimesOut_parkNanos() {
245 +        testParkTimesOut(ParkMethod.parkNanos);
246 +    }
247 +    public void testParkTimesOut_parkUntil() {
248 +        testParkTimesOut(ParkMethod.parkUntil);
249 +    }
250 +    public void testParkTimesOut_parkNanosBlocker() {
251 +        testParkTimesOut(ParkMethod.parkNanosBlocker);
252 +    }
253 +    public void testParkTimesOut_parkUntilBlocker() {
254 +        testParkTimesOut(ParkMethod.parkUntilBlocker);
255 +    }
256 +    public void testParkTimesOut(final ParkMethod parkMethod) {
257 +        Thread t = newStartedThread(new CheckedRunnable() {
258 +            public void realRun() {
259 +                for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
260 +                    long startTime = System.nanoTime();
261 +                    parkMethod.park(timeoutMillis());
262 +                    // park may return spuriously
263 +                    if (millisElapsedSince(startTime) >= timeoutMillis())
264 +                        return;
265 +                }
266 +                fail("too many consecutive spurious wakeups?");
267 +            }});
268 +
269 +        awaitTermination(t);
270 +    }
271 +
272 +    /**
273 +     * getBlocker(null) throws NullPointerException
274 +     */
275 +    public void testGetBlockerNull() {
276 +        try {
277 +            LockSupport.getBlocker(null);
278 +            shouldThrow();
279 +        } catch (NullPointerException success) {}
280 +    }
281  
282 <    public void testParkUntil() {
283 <        Thread t = new Thread(new Runnable(){
284 <                public void run(){
285 <                    try{
286 <                        long d = new Date().getTime() + 100;
287 <                        LockSupport.parkUntil(d);
288 <                    }catch(Exception e){
289 <                        fail("unexpected exception");
290 <                    }
291 <                }
292 <            });
293 <        try{
294 <            t.start();
295 <            t.join();
296 <        }
297 <        catch(Exception e) {
298 <            fail("unexpected exception");
282 >    /**
283 >     * getBlocker returns the blocker object passed to park
284 >     */
285 >    public void testGetBlocker_parkBlocker() {
286 >        testGetBlocker(ParkMethod.parkBlocker);
287 >    }
288 >    public void testGetBlocker_parkNanosBlocker() {
289 >        testGetBlocker(ParkMethod.parkNanosBlocker);
290 >    }
291 >    public void testGetBlocker_parkUntilBlocker() {
292 >        testGetBlocker(ParkMethod.parkUntilBlocker);
293 >    }
294 >    public void testGetBlocker(final ParkMethod parkMethod) {
295 >        final CountDownLatch started = new CountDownLatch(1);
296 >        Thread t = newStartedThread(new CheckedRunnable() {
297 >            public void realRun() {
298 >                Thread t = Thread.currentThread();
299 >                started.countDown();
300 >                do {
301 >                    assertNull(LockSupport.getBlocker(t));
302 >                    parkMethod.park();
303 >                    assertNull(LockSupport.getBlocker(t));
304 >                    // park may return spuriously
305 >                } while (! Thread.interrupted());
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 >                Thread.yield();
322 >            }
323          }
324      }
325  
326 +    /**
327 +     * timed park(0) returns immediately.
328 +     *
329 +     * Requires hotspot fix for:
330 +     * 6763959 java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
331 +     * which is in jdk7-b118 and 6u25.
332 +     */
333 +    public void testPark0_parkNanos() {
334 +        testPark0(ParkMethod.parkNanos);
335 +    }
336 +    public void testPark0_parkUntil() {
337 +        testPark0(ParkMethod.parkUntil);
338 +    }
339 +    public void testPark0_parkNanosBlocker() {
340 +        testPark0(ParkMethod.parkNanosBlocker);
341 +    }
342 +    public void testPark0_parkUntilBlocker() {
343 +        testPark0(ParkMethod.parkUntilBlocker);
344 +    }
345 +    public void testPark0(final ParkMethod parkMethod) {
346 +        Thread t = newStartedThread(new CheckedRunnable() {
347 +            public void realRun() {
348 +                parkMethod.park(0L);
349 +            }});
350 +
351 +        awaitTermination(t);
352 +    }
353 +
354 +    /**
355 +     * timed park(Long.MIN_VALUE) returns immediately.
356 +     */
357 +    public void testParkNeg_parkNanos() {
358 +        testParkNeg(ParkMethod.parkNanos);
359 +    }
360 +    public void testParkNeg_parkUntil() {
361 +        testParkNeg(ParkMethod.parkUntil);
362 +    }
363 +    public void testParkNeg_parkNanosBlocker() {
364 +        testParkNeg(ParkMethod.parkNanosBlocker);
365 +    }
366 +    public void testParkNeg_parkUntilBlocker() {
367 +        testParkNeg(ParkMethod.parkUntilBlocker);
368 +    }
369 +    public void testParkNeg(final ParkMethod parkMethod) {
370 +        Thread t = newStartedThread(new CheckedRunnable() {
371 +            public void realRun() {
372 +                parkMethod.park(Long.MIN_VALUE);
373 +            }});
374  
375 +        awaitTermination(t);
376 +    }
377   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines