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.23 by jsr166, Sat May 28 22:21:58 2011 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.*;
11 < import java.util.*;
12 < import java.util.concurrent.*;
13 < import java.util.concurrent.locks.*;
14 <
13 < public class LockSupportTest extends TestCase{
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      }
18    
20  
21      public static Test suite() {
22 <        return new TestSuite(LockSupportTest.class);
22 >        return new TestSuite(LockSupportTest.class);
23      }
24  
25 <    public void testUnpark() {
26 <        Thread t = new Thread(new Runnable(){
27 <                public void run(){
28 <                    try{
29 <                        LockSupport.park();
30 <                    }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 <        }
25 >    /**
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 >    static Object theBlocker() {
30 >        return LockSupportTest.class;
31      }
32  
33 <    public void testParkNanos() {
34 <        Thread t = new Thread(new Runnable(){
35 <                public void run(){
36 <                    try{
37 <                        LockSupport.parkNanos(1000);
38 <                    }catch(Exception e){
39 <                        fail("unexpected exception");
40 <                    }
41 <                }
42 <            });
43 <        try{
44 <            t.start();
45 <            t.join();
46 <        }
47 <        catch(Exception e) {
48 <            fail("unexpected exception");
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 +        await(pleaseUnpark);
112 +        LockSupport.unpark(t);
113 +        awaitTermination(t);
114 +    }
115 +
116 +    /**
117 +     * park is released by preceding unpark
118 +     */
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 +        await(pleaseUnpark);
149 +        LockSupport.unpark(t);
150 +        pleasePark.set(true);
151 +        awaitTermination(t);
152 +    }
153 +
154 +    /**
155 +     * park is released by subsequent interrupt
156 +     */
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 +        await(pleaseInterrupt);
187 +        assertThreadStaysAlive(t);
188 +        t.interrupt();
189 +        awaitTermination(t);
190 +    }
191 +
192 +    /**
193 +     * park is released by preceding interrupt
194 +     */
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 +        await(pleaseInterrupt);
227 +        t.interrupt();
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 +     * getBlocker returns the blocker object passed to park
274 +     */
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 <    public void testParkUntil() {
299 <        Thread t = new Thread(new Runnable(){
300 <                public void run(){
301 <                    try{
302 <                        long d = new Date().getTime() + 100;
303 <                        LockSupport.parkUntil(d);
304 <                    }catch(Exception e){
305 <                        fail("unexpected exception");
306 <                    }
307 <                }
308 <            });
309 <        try{
310 <            t.start();
311 <            t.join();
312 <        }
79 <        catch(Exception e) {
80 <            fail("unexpected exception");
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 +     * timed park(Long.MIN_VALUE) returns immediately.
346 +     */
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 +        awaitTermination(t);
366 +    }
367   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines