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.11 by jsr166, Tue Nov 17 12:46:10 2009 UTC vs.
Revision 1.23 by jsr166, Sat May 28 22:21:58 2011 UTC

# Line 1 | Line 1
1   /*
2 < * Written by Doug Lea with assistance from members of JCP JSR-166
3 < * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
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.*;
12 < import java.util.concurrent.*;
13 < import java.util.concurrent.locks.*;
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());
18 >        junit.textui.TestRunner.run(suite());
19      }
20 +
21      public static Test suite() {
22 <        return new TestSuite(LockSupportTest.class);
22 >        return new TestSuite(LockSupportTest.class);
23      }
24  
25      /**
26 <     * park is released by unpark occurring after park
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 <    public void testPark() throws InterruptedException {
30 <        Thread t = new Thread(new CheckedRunnable() {
31 <            public void realRun() {
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 <        t.start();
32 <        Thread.sleep(SHORT_DELAY_MS);
111 >        await(pleaseUnpark);
112          LockSupport.unpark(t);
113 <        t.join();
113 >        awaitTermination(t);
114      }
115  
116      /**
117 <     * park is released by unpark occurring before park
117 >     * park is released by preceding unpark
118       */
119 <    public void testPark2() throws InterruptedException {
120 <        Thread t = new Thread(new CheckedRunnable() {
121 <            public void realRun() throws InterruptedException {
122 <                Thread.sleep(SHORT_DELAY_MS);
123 <                LockSupport.park();
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 <        t.start();
148 >        await(pleaseUnpark);
149          LockSupport.unpark(t);
150 <        t.join();
150 >        pleasePark.set(true);
151 >        awaitTermination(t);
152      }
153  
154      /**
155 <     * park is released by interrupt
155 >     * park is released by subsequent interrupt
156       */
157 <    public void testPark3() throws InterruptedException {
158 <        Thread t = new Thread(new CheckedRunnable() {
159 <            public void realRun() {
160 <                LockSupport.park();
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 <        t.start();
187 <        Thread.sleep(SHORT_DELAY_MS);
186 >        await(pleaseInterrupt);
187 >        assertThreadStaysAlive(t);
188          t.interrupt();
189 <        t.join();
189 >        awaitTermination(t);
190      }
191  
192      /**
193 <     * park returns if interrupted before park
193 >     * park is released by preceding interrupt
194       */
195 <    public void testPark4() throws InterruptedException {
196 <        final ReentrantLock lock = new ReentrantLock();
197 <        lock.lock();
198 <        Thread t = new Thread(new CheckedRunnable() {
199 <            public void realRun() {
200 <                lock.lock();
201 <                LockSupport.park();
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 <        t.start();
226 >        await(pleaseInterrupt);
227          t.interrupt();
228 <        lock.unlock();
229 <        t.join();
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 <     * parkNanos times out if not unparked
273 >     * getBlocker returns the blocker object passed to park
274       */
275 <    public void testParkNanos() throws InterruptedException {
276 <        Thread t = new Thread(new CheckedRunnable() {
277 <            public void realRun() {
278 <                LockSupport.parkNanos(1000);
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 <        t.start();
299 <        t.join();
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 <     * parkUntil times out if not unparked
345 >     * timed park(Long.MIN_VALUE) returns immediately.
346       */
347 <    public void testParkUntil() throws InterruptedException {
348 <        Thread t = new Thread(new CheckedRunnable() {
349 <            public void realRun() {
350 <                long d = new Date().getTime() + 100;
351 <                LockSupport.parkUntil(d);
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 <        t.start();
110 <        t.join();
365 >        awaitTermination(t);
366      }
367   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines