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

Comparing jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java (file contents):
Revision 1.6 by dl, Wed Dec 31 21:30:08 2003 UTC vs.
Revision 1.20 by dl, Fri Feb 24 00:03:16 2006 UTC

# Line 22 | Line 22 | public class AbstractQueuedSynchronizerT
22      }
23  
24      /**
25 <     * A simple mutex class, from the AbstractQueuedSynchronizer
26 <     * javadoc.  All tests exercise this as a sample user extension.
27 <     * Other methods/features of AbstractQueuedSynchronizerTest are
28 <     * tested implicitly in ReentrantLock, ReentrantReadWriteLock, and
29 <     * Semaphore test classes
30 <     */
31 <    static class Mutex implements Lock, java.io.Serializable {
32 <        private static class Sync extends AbstractQueuedSynchronizer {
33 <            boolean isLocked() { return getState() == 1; }
34 <
35 <            public boolean tryAcquireExclusiveState(boolean isQueued, int acquires) {
36 <                assert acquires == 1; // Does not use multiple acquires
37 <                return compareAndSetState(0, 1);
38 <            }
39 <            
40 <            public boolean releaseExclusiveState(int releases) {
41 <                setState(0);
42 <                return true;
43 <            }
44 <            
45 <            public void checkConditionAccess(Thread thread, boolean waiting) {
46 <                if (getState() == 0) throw new IllegalMonitorStateException();
47 <            }
48 <            
49 <            Condition newCondition() { return new ConditionObject(); }
50 <            
51 <            private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
52 <                s.defaultReadObject();
53 <                setState(0); // reset to unlocked state
54 <            }
55 <        }
25 >     * A simple mutex class, adapted from the
26 >     * AbstractQueuedSynchronizer javadoc.  Exclusive acquire tests
27 >     * exercise this as a sample user extension.  Other
28 >     * methods/features of AbstractQueuedSynchronizerTest are tested
29 >     * via other test classes, including those for ReentrantLock,
30 >     * ReentrantReadWriteLock, and Semaphore
31 >     */
32 >    static class Mutex extends AbstractQueuedSynchronizer {
33 >        public boolean isHeldExclusively() { return getState() == 1; }
34          
35 <        private final Sync sync = new Sync();
36 <        public boolean tryLock() {
37 <            return sync.tryAcquireExclusiveState(false, 1);
35 >        public boolean tryAcquire(int acquires) {
36 >            assertTrue(acquires == 1);
37 >            return compareAndSetState(0, 1);
38          }
39 <        public void lock() {
40 <            sync.acquireExclusiveUninterruptibly(1);
39 >        
40 >        public boolean tryRelease(int releases) {
41 >            if (getState() == 0) throw new IllegalMonitorStateException();
42 >            setState(0);
43 >            return true;
44          }
45 <        public void lockInterruptibly() throws InterruptedException {
46 <            sync.acquireExclusiveInterruptibly(1);
45 >        
46 >        public AbstractQueuedSynchronizer.ConditionObject newCondition() { return new AbstractQueuedSynchronizer.ConditionObject(); }
47 >
48 >    }
49 >
50 >    
51 >    /**
52 >     * A simple latch class, to test shared mode.
53 >     */
54 >    static class BooleanLatch extends AbstractQueuedSynchronizer {
55 >        public boolean isSignalled() { return getState() != 0; }
56 >
57 >        public int tryAcquireShared(int ignore) {
58 >            return isSignalled()? 1 : -1;
59          }
60 <        public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
61 <            return sync.acquireExclusiveTimed(1, unit.toNanos(timeout));
60 >        
61 >        public boolean tryReleaseShared(int ignore) {
62 >            setState(1);
63 >            return true;
64          }
70        public void unlock() { sync.releaseExclusive(1); }
71        public Condition newCondition() { return sync.newCondition(); }
72        public boolean isLocked() { return sync.isLocked(); }
73        public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
65      }
66  
67      /**
68 <     * A runnable calling lockInterruptibly
68 >     * A runnable calling acquireInterruptibly
69       */
70 <    class InterruptibleLockRunnable implements Runnable {
71 <        final Mutex lock;
72 <        InterruptibleLockRunnable(Mutex l) { lock = l; }
70 >    class InterruptibleSyncRunnable implements Runnable {
71 >        final Mutex sync;
72 >        InterruptibleSyncRunnable(Mutex l) { sync = l; }
73          public void run() {
74              try {
75 <                lock.lockInterruptibly();
75 >                sync.acquireInterruptibly(1);
76              } catch(InterruptedException success){}
77          }
78      }
79  
80  
81      /**
82 <     * A runnable calling lockInterruptibly that expects to be
82 >     * A runnable calling acquireInterruptibly that expects to be
83       * interrupted
84       */
85 <    class InterruptedLockRunnable implements Runnable {
86 <        final Mutex lock;
87 <        InterruptedLockRunnable(Mutex l) { lock = l; }
85 >    class InterruptedSyncRunnable implements Runnable {
86 >        final Mutex sync;
87 >        InterruptedSyncRunnable(Mutex l) { sync = l; }
88          public void run() {
89              try {
90 <                lock.lockInterruptibly();
90 >                sync.acquireInterruptibly(1);
91                  threadShouldThrow();
92              } catch(InterruptedException success){}
93          }
94      }
95 +
96 +    /**
97 +     * isHeldExclusively is false upon construction
98 +     */
99 +    public void testIsHeldExclusively() {
100 +        Mutex rl = new Mutex();
101 +        assertFalse(rl.isHeldExclusively());
102 +    }
103      
104      /**
105 <     * locking an unlocked lock succeeds
105 >     * acquiring released sync succeeds
106       */
107 <    public void testLock() {
107 >    public void testAcquire() {
108          Mutex rl = new Mutex();
109 <        rl.lock();
110 <        assertTrue(rl.isLocked());
111 <        rl.unlock();
109 >        rl.acquire(1);
110 >        assertTrue(rl.isHeldExclusively());
111 >        rl.release(1);
112 >        assertFalse(rl.isHeldExclusively());
113      }
114  
115      /**
116 <     * tryLock on an unlocked lock succeeds
116 >     * tryAcquire on an released sync succeeds
117       */
118 <    public void testTryLock() {
118 >    public void testTryAcquire() {
119          Mutex rl = new Mutex();
120 <        assertTrue(rl.tryLock());
121 <        assertTrue(rl.isLocked());
122 <        rl.unlock();
120 >        assertTrue(rl.tryAcquire(1));
121 >        assertTrue(rl.isHeldExclusively());
122 >        rl.release(1);
123      }
124  
125      /**
126       * hasQueuedThreads reports whether there are waiting threads
127       */
128      public void testhasQueuedThreads() {
129 <        final Mutex lock = new Mutex();
130 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
131 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
129 >        final Mutex sync = new Mutex();
130 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
131 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
132 >        try {
133 >            assertFalse(sync.hasQueuedThreads());
134 >            sync.acquire(1);
135 >            t1.start();
136 >            Thread.sleep(SHORT_DELAY_MS);
137 >            assertTrue(sync.hasQueuedThreads());
138 >            t2.start();
139 >            Thread.sleep(SHORT_DELAY_MS);
140 >            assertTrue(sync.hasQueuedThreads());
141 >            t1.interrupt();
142 >            Thread.sleep(SHORT_DELAY_MS);
143 >            assertTrue(sync.hasQueuedThreads());
144 >            sync.release(1);
145 >            Thread.sleep(SHORT_DELAY_MS);
146 >            assertFalse(sync.hasQueuedThreads());
147 >            t1.join();
148 >            t2.join();
149 >        } catch(Exception e){
150 >            unexpectedException();
151 >        }
152 >    }
153 >
154 >    /**
155 >     * isQueued(null) throws NPE
156 >     */
157 >    public void testIsQueuedNPE() {
158 >        final Mutex sync = new Mutex();
159 >        try {
160 >            sync.isQueued(null);
161 >            shouldThrow();
162 >        } catch (NullPointerException success) {
163 >        }
164 >    }
165 >
166 >    /**
167 >     * isQueued reports whether a thread is queued.
168 >     */
169 >    public void testIsQueued() {
170 >        final Mutex sync = new Mutex();
171 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
172 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
173 >        try {
174 >            assertFalse(sync.isQueued(t1));
175 >            assertFalse(sync.isQueued(t2));
176 >            sync.acquire(1);
177 >            t1.start();
178 >            Thread.sleep(SHORT_DELAY_MS);
179 >            assertTrue(sync.isQueued(t1));
180 >            t2.start();
181 >            Thread.sleep(SHORT_DELAY_MS);
182 >            assertTrue(sync.isQueued(t1));
183 >            assertTrue(sync.isQueued(t2));
184 >            t1.interrupt();
185 >            Thread.sleep(SHORT_DELAY_MS);
186 >            assertFalse(sync.isQueued(t1));
187 >            assertTrue(sync.isQueued(t2));
188 >            sync.release(1);
189 >            Thread.sleep(SHORT_DELAY_MS);
190 >            assertFalse(sync.isQueued(t1));
191 >            Thread.sleep(SHORT_DELAY_MS);
192 >            assertFalse(sync.isQueued(t2));
193 >            t1.join();
194 >            t2.join();
195 >        } catch(Exception e){
196 >            unexpectedException();
197 >        }
198 >    }
199 >
200 >    /**
201 >     * getFirstQueuedThread returns first waiting thread or null if none
202 >     */
203 >    public void testGetFirstQueuedThread() {
204 >        final Mutex sync = new Mutex();
205 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
206 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
207 >        try {
208 >            assertNull(sync.getFirstQueuedThread());
209 >            sync.acquire(1);
210 >            t1.start();
211 >            Thread.sleep(SHORT_DELAY_MS);
212 >            assertEquals(t1, sync.getFirstQueuedThread());
213 >            t2.start();
214 >            Thread.sleep(SHORT_DELAY_MS);
215 >            assertEquals(t1, sync.getFirstQueuedThread());
216 >            t1.interrupt();
217 >            Thread.sleep(SHORT_DELAY_MS);
218 >            Thread.sleep(SHORT_DELAY_MS);
219 >            assertEquals(t2, sync.getFirstQueuedThread());
220 >            sync.release(1);
221 >            Thread.sleep(SHORT_DELAY_MS);
222 >            assertNull(sync.getFirstQueuedThread());
223 >            t1.join();
224 >            t2.join();
225 >        } catch(Exception e){
226 >            unexpectedException();
227 >        }
228 >    }
229 >
230 >
231 >    /**
232 >     * hasContended reports false if no thread has ever blocked, else true
233 >     */
234 >    public void testHasContended() {
235 >        final Mutex sync = new Mutex();
236 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
237 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
238 >        try {
239 >            assertFalse(sync.hasContended());
240 >            sync.acquire(1);
241 >            t1.start();
242 >            Thread.sleep(SHORT_DELAY_MS);
243 >            assertTrue(sync.hasContended());
244 >            t2.start();
245 >            Thread.sleep(SHORT_DELAY_MS);
246 >            assertTrue(sync.hasContended());
247 >            t1.interrupt();
248 >            Thread.sleep(SHORT_DELAY_MS);
249 >            assertTrue(sync.hasContended());
250 >            sync.release(1);
251 >            Thread.sleep(SHORT_DELAY_MS);
252 >            assertTrue(sync.hasContended());
253 >            t1.join();
254 >            t2.join();
255 >        } catch(Exception e){
256 >            unexpectedException();
257 >        }
258 >    }
259 >
260 >    /**
261 >     * getQueuedThreads includes waiting threads
262 >     */
263 >    public void testGetQueuedThreads() {
264 >        final Mutex sync = new Mutex();
265 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
266 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
267 >        try {
268 >            assertTrue(sync.getQueuedThreads().isEmpty());
269 >            sync.acquire(1);
270 >            assertTrue(sync.getQueuedThreads().isEmpty());
271 >            t1.start();
272 >            Thread.sleep(SHORT_DELAY_MS);
273 >            assertTrue(sync.getQueuedThreads().contains(t1));
274 >            t2.start();
275 >            Thread.sleep(SHORT_DELAY_MS);
276 >            assertTrue(sync.getQueuedThreads().contains(t1));
277 >            assertTrue(sync.getQueuedThreads().contains(t2));
278 >            t1.interrupt();
279 >            Thread.sleep(SHORT_DELAY_MS);
280 >            assertFalse(sync.getQueuedThreads().contains(t1));
281 >            assertTrue(sync.getQueuedThreads().contains(t2));
282 >            sync.release(1);
283 >            Thread.sleep(SHORT_DELAY_MS);
284 >            assertTrue(sync.getQueuedThreads().isEmpty());
285 >            t1.join();
286 >            t2.join();
287 >        } catch(Exception e){
288 >            unexpectedException();
289 >        }
290 >    }
291 >
292 >    /**
293 >     * getExclusiveQueuedThreads includes waiting threads
294 >     */
295 >    public void testGetExclusiveQueuedThreads() {
296 >        final Mutex sync = new Mutex();
297 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
298 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
299          try {
300 <            assertFalse(lock.hasQueuedThreads());
301 <            lock.lock();
300 >            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
301 >            sync.acquire(1);
302 >            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
303              t1.start();
304              Thread.sleep(SHORT_DELAY_MS);
305 <            assertTrue(lock.hasQueuedThreads());
305 >            assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
306              t2.start();
307              Thread.sleep(SHORT_DELAY_MS);
308 <            assertTrue(lock.hasQueuedThreads());
308 >            assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
309 >            assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
310              t1.interrupt();
311              Thread.sleep(SHORT_DELAY_MS);
312 <            assertTrue(lock.hasQueuedThreads());
313 <            lock.unlock();
312 >            assertFalse(sync.getExclusiveQueuedThreads().contains(t1));
313 >            assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
314 >            sync.release(1);
315              Thread.sleep(SHORT_DELAY_MS);
316 <            assertFalse(lock.hasQueuedThreads());
316 >            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
317              t1.join();
318              t2.join();
319          } catch(Exception e){
# Line 152 | Line 322 | public class AbstractQueuedSynchronizerT
322      }
323  
324      /**
325 <     * timed tryLock is interruptible.
325 >     * getSharedQueuedThreads does not include exclusively waiting threads
326 >     */
327 >    public void testGetSharedQueuedThreads() {
328 >        final Mutex sync = new Mutex();
329 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
330 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
331 >        try {
332 >            assertTrue(sync.getSharedQueuedThreads().isEmpty());
333 >            sync.acquire(1);
334 >            assertTrue(sync.getSharedQueuedThreads().isEmpty());
335 >            t1.start();
336 >            Thread.sleep(SHORT_DELAY_MS);
337 >            assertTrue(sync.getSharedQueuedThreads().isEmpty());
338 >            t2.start();
339 >            Thread.sleep(SHORT_DELAY_MS);
340 >            assertTrue(sync.getSharedQueuedThreads().isEmpty());
341 >            t1.interrupt();
342 >            Thread.sleep(SHORT_DELAY_MS);
343 >            assertTrue(sync.getSharedQueuedThreads().isEmpty());
344 >            sync.release(1);
345 >            Thread.sleep(SHORT_DELAY_MS);
346 >            assertTrue(sync.getSharedQueuedThreads().isEmpty());
347 >            t1.join();
348 >            t2.join();
349 >        } catch(Exception e){
350 >            unexpectedException();
351 >        }
352 >    }
353 >
354 >    /**
355 >     * tryAcquireNanos is interruptible.
356       */
357      public void testInterruptedException2() {
358 <        final Mutex lock = new Mutex();
359 <        lock.lock();
358 >        final Mutex sync = new Mutex();
359 >        sync.acquire(1);
360          Thread t = new Thread(new Runnable() {
361                  public void run() {
362                      try {
363 <                        lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS);
363 >                        sync.tryAcquireNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
364                          threadShouldThrow();
365                      } catch(InterruptedException success){}
366                  }
# Line 175 | Line 375 | public class AbstractQueuedSynchronizerT
375  
376  
377      /**
378 <     * TryLock on a locked lock fails
378 >     * TryAcquire on exclusively held sync fails
379       */
380 <    public void testTryLockWhenLocked() {
381 <        final Mutex lock = new Mutex();
382 <        lock.lock();
380 >    public void testTryAcquireWhenSynced() {
381 >        final Mutex sync = new Mutex();
382 >        sync.acquire(1);
383          Thread t = new Thread(new Runnable() {
384                  public void run() {
385 <                    threadAssertFalse(lock.tryLock());
385 >                    threadAssertFalse(sync.tryAcquire(1));
386                  }
387              });
388          try {
389              t.start();
390              t.join();
391 <            lock.unlock();
391 >            sync.release(1);
392          } catch(Exception e){
393              unexpectedException();
394          }
395      }
396  
397      /**
398 <     * Timed tryLock on a locked lock times out
398 >     * tryAcquireNanos on an exclusively held sync times out
399       */
400 <    public void testTryLock_Timeout() {
401 <        final Mutex lock = new Mutex();
402 <        lock.lock();
400 >    public void testAcquireNanos_Timeout() {
401 >        final Mutex sync = new Mutex();
402 >        sync.acquire(1);
403          Thread t = new Thread(new Runnable() {
404                  public void run() {
405                      try {
406 <                        threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS));
406 >                        threadAssertFalse(sync.tryAcquireNanos(1, 1000 * 1000));
407                      } catch (Exception ex) {
408                          threadUnexpectedException();
409                      }
# Line 212 | Line 412 | public class AbstractQueuedSynchronizerT
412          try {
413              t.start();
414              t.join();
415 <            lock.unlock();
415 >            sync.release(1);
416          } catch(Exception e){
417              unexpectedException();
418          }
# Line 220 | Line 420 | public class AbstractQueuedSynchronizerT
420      
421    
422      /**
423 <     * isLocked is true when locked and false when not
423 >     * getState is true when acquired and false when not
424       */
425 <    public void testIsLocked() {
426 <        final Mutex lock = new Mutex();
427 <        lock.lock();
428 <        assertTrue(lock.isLocked());
429 <        lock.unlock();
430 <        assertFalse(lock.isLocked());
425 >    public void testGetState() {
426 >        final Mutex sync = new Mutex();
427 >        sync.acquire(1);
428 >        assertTrue(sync.isHeldExclusively());
429 >        sync.release(1);
430 >        assertFalse(sync.isHeldExclusively());
431          Thread t = new Thread(new Runnable() {
432                  public void run() {
433 <                    lock.lock();
433 >                    sync.acquire(1);
434                      try {
435                          Thread.sleep(SMALL_DELAY_MS);
436                      }
437                      catch(Exception e) {
438                          threadUnexpectedException();
439                      }
440 <                    lock.unlock();
440 >                    sync.release(1);
441                  }
442              });
443          try {
444              t.start();
445              Thread.sleep(SHORT_DELAY_MS);
446 <            assertTrue(lock.isLocked());
446 >            assertTrue(sync.isHeldExclusively());
447              t.join();
448 <            assertFalse(lock.isLocked());
448 >            assertFalse(sync.isHeldExclusively());
449          } catch(Exception e){
450              unexpectedException();
451          }
# Line 253 | Line 453 | public class AbstractQueuedSynchronizerT
453  
454  
455      /**
456 <     * lockInterruptibly is interruptible.
456 >     * acquireInterruptibly is interruptible.
457       */
458 <    public void testLockInterruptibly1() {
459 <        final Mutex lock = new Mutex();
460 <        lock.lock();
461 <        Thread t = new Thread(new InterruptedLockRunnable(lock));
458 >    public void testAcquireInterruptibly1() {
459 >        final Mutex sync = new Mutex();
460 >        sync.acquire(1);
461 >        Thread t = new Thread(new InterruptedSyncRunnable(sync));
462          try {
463              t.start();
464 +            Thread.sleep(SHORT_DELAY_MS);
465              t.interrupt();
466 <            lock.unlock();
466 >            sync.release(1);
467              t.join();
468          } catch(Exception e){
469              unexpectedException();
# Line 270 | Line 471 | public class AbstractQueuedSynchronizerT
471      }
472  
473      /**
474 <     * lockInterruptibly succeeds when unlocked, else is interruptible
474 >     * acquireInterruptibly succeeds when released, else is interruptible
475       */
476 <    public void testLockInterruptibly2() {
477 <        final Mutex lock = new Mutex();
476 >    public void testAcquireInterruptibly2() {
477 >        final Mutex sync = new Mutex();
478          try {
479 <            lock.lockInterruptibly();
479 >            sync.acquireInterruptibly(1);
480          } catch(Exception e) {
481              unexpectedException();
482          }
483 <        Thread t = new Thread(new InterruptedLockRunnable(lock));
483 >        Thread t = new Thread(new InterruptedSyncRunnable(sync));
484          try {
485              t.start();
486              t.interrupt();
487 <            assertTrue(lock.isLocked());
487 >            assertTrue(sync.isHeldExclusively());
488              t.join();
489          } catch(Exception e){
490              unexpectedException();
# Line 291 | Line 492 | public class AbstractQueuedSynchronizerT
492      }
493  
494      /**
495 <     * Calling await without holding lock throws IllegalMonitorStateException
495 >     * owns is true for a condition created by sync else false
496 >     */
497 >    public void testOwns() {
498 >        final Mutex sync = new Mutex();
499 >        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
500 >        final Mutex sync2 = new Mutex();
501 >        assertTrue(sync.owns(c));
502 >        assertFalse(sync2.owns(c));
503 >    }
504 >
505 >    /**
506 >     * Calling await without holding sync throws IllegalMonitorStateException
507       */
508      public void testAwait_IllegalMonitor() {
509 <        final Mutex lock = new Mutex();
510 <        final Condition c = lock.newCondition();
509 >        final Mutex sync = new Mutex();
510 >        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
511          try {
512              c.await();
513              shouldThrow();
# Line 308 | Line 520 | public class AbstractQueuedSynchronizerT
520      }
521  
522      /**
523 <     * Calling signal without holding lock throws IllegalMonitorStateException
523 >     * Calling signal without holding sync throws IllegalMonitorStateException
524       */
525      public void testSignal_IllegalMonitor() {
526 <        final Mutex lock = new Mutex();
527 <        final Condition c = lock.newCondition();
526 >        final Mutex sync = new Mutex();
527 >        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
528          try {
529              c.signal();
530              shouldThrow();
# Line 328 | Line 540 | public class AbstractQueuedSynchronizerT
540       * awaitNanos without a signal times out
541       */
542      public void testAwaitNanos_Timeout() {
543 <        final Mutex lock = new Mutex();
544 <        final Condition c = lock.newCondition();
543 >        final Mutex sync = new Mutex();
544 >        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
545          try {
546 <            lock.lock();
546 >            sync.acquire(1);
547              long t = c.awaitNanos(100);
548              assertTrue(t <= 0);
549 <            lock.unlock();
549 >            sync.release(1);
550          }
551          catch (Exception ex) {
552              unexpectedException();
# Line 342 | Line 554 | public class AbstractQueuedSynchronizerT
554      }
555  
556      /**
557 <     *  timed await without a signal times out
557 >     *  Timed await without a signal times out
558       */
559      public void testAwait_Timeout() {
560 <        final Mutex lock = new Mutex();
561 <        final Condition c = lock.newCondition();
560 >        final Mutex sync = new Mutex();
561 >        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
562          try {
563 <            lock.lock();
563 >            sync.acquire(1);
564              assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
565 <            lock.unlock();
565 >            sync.release(1);
566          }
567          catch (Exception ex) {
568              unexpectedException();
# Line 361 | Line 573 | public class AbstractQueuedSynchronizerT
573       * awaitUntil without a signal times out
574       */
575      public void testAwaitUntil_Timeout() {
576 <        final Mutex lock = new Mutex();
577 <        final Condition c = lock.newCondition();
576 >        final Mutex sync = new Mutex();
577 >        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
578          try {
579 <            lock.lock();
579 >            sync.acquire(1);
580              java.util.Date d = new java.util.Date();
581              assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
582 <            lock.unlock();
582 >            sync.release(1);
583          }
584          catch (Exception ex) {
585              unexpectedException();
# Line 378 | Line 590 | public class AbstractQueuedSynchronizerT
590       * await returns when signalled
591       */
592      public void testAwait() {
593 <        final Mutex lock = new Mutex();
594 <        final Condition c = lock.newCondition();
593 >        final Mutex sync = new Mutex();
594 >        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
595 >        Thread t = new Thread(new Runnable() {
596 >                public void run() {
597 >                    try {
598 >                        sync.acquire(1);
599 >                        c.await();
600 >                        sync.release(1);
601 >                    }
602 >                    catch(InterruptedException e) {
603 >                        threadUnexpectedException();
604 >                    }
605 >                }
606 >            });
607 >
608 >        try {
609 >            t.start();
610 >            Thread.sleep(SHORT_DELAY_MS);
611 >            sync.acquire(1);
612 >            c.signal();
613 >            sync.release(1);
614 >            t.join(SHORT_DELAY_MS);
615 >            assertFalse(t.isAlive());
616 >        }
617 >        catch (Exception ex) {
618 >            unexpectedException();
619 >        }
620 >    }
621 >
622 >
623 >
624 >    /**
625 >     * hasWaiters throws NPE if null
626 >     */
627 >    public void testHasWaitersNPE() {
628 >        final Mutex sync = new Mutex();
629 >        try {
630 >            sync.hasWaiters(null);
631 >            shouldThrow();
632 >        } catch (NullPointerException success) {
633 >        } catch (Exception ex) {
634 >            unexpectedException();
635 >        }
636 >    }
637 >
638 >    /**
639 >     * getWaitQueueLength throws NPE if null
640 >     */
641 >    public void testGetWaitQueueLengthNPE() {
642 >        final Mutex sync = new Mutex();
643 >        try {
644 >            sync.getWaitQueueLength(null);
645 >            shouldThrow();
646 >        } catch (NullPointerException success) {
647 >        } catch (Exception ex) {
648 >            unexpectedException();
649 >        }
650 >    }
651 >
652 >
653 >    /**
654 >     * getWaitingThreads throws NPE if null
655 >     */
656 >    public void testGetWaitingThreadsNPE() {
657 >        final Mutex sync = new Mutex();
658 >        try {
659 >            sync.getWaitingThreads(null);
660 >            shouldThrow();
661 >        } catch (NullPointerException success) {
662 >        } catch (Exception ex) {
663 >            unexpectedException();
664 >        }
665 >    }
666 >
667 >
668 >    /**
669 >     * hasWaiters throws IAE if not owned
670 >     */
671 >    public void testHasWaitersIAE() {
672 >        final Mutex sync = new Mutex();
673 >        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
674 >        final Mutex sync2 = new Mutex();
675 >        try {
676 >            sync2.hasWaiters(c);
677 >            shouldThrow();
678 >        } catch (IllegalArgumentException success) {
679 >        } catch (Exception ex) {
680 >            unexpectedException();
681 >        }
682 >    }
683 >
684 >    /**
685 >     * hasWaiters throws IMSE if not synced
686 >     */
687 >    public void testHasWaitersIMSE() {
688 >        final Mutex sync = new Mutex();
689 >        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
690 >        try {
691 >            sync.hasWaiters(c);
692 >            shouldThrow();
693 >        } catch (IllegalMonitorStateException success) {
694 >        } catch (Exception ex) {
695 >            unexpectedException();
696 >        }
697 >    }
698 >
699 >
700 >    /**
701 >     * getWaitQueueLength throws IAE if not owned
702 >     */
703 >    public void testGetWaitQueueLengthIAE() {
704 >        final Mutex sync = new Mutex();
705 >        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
706 >        final Mutex sync2 = new Mutex();
707 >        try {
708 >            sync2.getWaitQueueLength(c);
709 >            shouldThrow();
710 >        } catch (IllegalArgumentException success) {
711 >        } catch (Exception ex) {
712 >            unexpectedException();
713 >        }
714 >    }
715 >
716 >    /**
717 >     * getWaitQueueLength throws IMSE if not synced
718 >     */
719 >    public void testGetWaitQueueLengthIMSE() {
720 >        final Mutex sync = new Mutex();
721 >        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
722 >        try {
723 >            sync.getWaitQueueLength(c);
724 >            shouldThrow();
725 >        } catch (IllegalMonitorStateException success) {
726 >        } catch (Exception ex) {
727 >            unexpectedException();
728 >        }
729 >    }
730 >
731 >
732 >    /**
733 >     * getWaitingThreads throws IAE if not owned
734 >     */
735 >    public void testGetWaitingThreadsIAE() {
736 >        final Mutex sync = new Mutex();
737 >        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
738 >        final Mutex sync2 = new Mutex();        
739 >        try {
740 >            sync2.getWaitingThreads(c);
741 >            shouldThrow();
742 >        } catch (IllegalArgumentException success) {
743 >        } catch (Exception ex) {
744 >            unexpectedException();
745 >        }
746 >    }
747 >
748 >    /**
749 >     * getWaitingThreads throws IMSE if not synced
750 >     */
751 >    public void testGetWaitingThreadsIMSE() {
752 >        final Mutex sync = new Mutex();
753 >        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
754 >        try {
755 >            sync.getWaitingThreads(c);
756 >            shouldThrow();
757 >        } catch (IllegalMonitorStateException success) {
758 >        } catch (Exception ex) {
759 >            unexpectedException();
760 >        }
761 >    }
762 >
763 >
764 >
765 >    /**
766 >     * hasWaiters returns true when a thread is waiting, else false
767 >     */
768 >    public void testHasWaiters() {
769 >        final Mutex sync = new Mutex();
770 >        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
771          Thread t = new Thread(new Runnable() {
772                  public void run() {
773                      try {
774 <                        lock.lock();
774 >                        sync.acquire(1);
775 >                        threadAssertFalse(sync.hasWaiters(c));
776 >                        threadAssertEquals(0, sync.getWaitQueueLength(c));
777                          c.await();
778 <                        lock.unlock();
778 >                        sync.release(1);
779                      }
780                      catch(InterruptedException e) {
781                          threadUnexpectedException();
# Line 396 | Line 786 | public class AbstractQueuedSynchronizerT
786          try {
787              t.start();
788              Thread.sleep(SHORT_DELAY_MS);
789 <            lock.lock();
789 >            sync.acquire(1);
790 >            assertTrue(sync.hasWaiters(c));
791 >            assertEquals(1, sync.getWaitQueueLength(c));
792              c.signal();
793 <            lock.unlock();
793 >            sync.release(1);
794 >            Thread.sleep(SHORT_DELAY_MS);
795 >            sync.acquire(1);
796 >            assertFalse(sync.hasWaiters(c));
797 >            assertEquals(0, sync.getWaitQueueLength(c));
798 >            sync.release(1);
799              t.join(SHORT_DELAY_MS);
800              assertFalse(t.isAlive());
801          }
# Line 406 | Line 803 | public class AbstractQueuedSynchronizerT
803              unexpectedException();
804          }
805      }
806 +
807 +    /**
808 +     * getWaitQueueLength returns number of waiting threads
809 +     */
810 +    public void testGetWaitQueueLength() {
811 +        final Mutex sync = new Mutex();
812 +        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
813 +        Thread t1 = new Thread(new Runnable() {
814 +                public void run() {
815 +                    try {
816 +                        sync.acquire(1);
817 +                        threadAssertFalse(sync.hasWaiters(c));
818 +                        threadAssertEquals(0, sync.getWaitQueueLength(c));
819 +                        c.await();
820 +                        sync.release(1);
821 +                    }
822 +                    catch(InterruptedException e) {
823 +                        threadUnexpectedException();
824 +                    }
825 +                }
826 +            });
827 +
828 +        Thread t2 = new Thread(new Runnable() {
829 +                public void run() {
830 +                    try {
831 +                        sync.acquire(1);
832 +                        threadAssertTrue(sync.hasWaiters(c));
833 +                        threadAssertEquals(1, sync.getWaitQueueLength(c));
834 +                        c.await();
835 +                        sync.release(1);
836 +                    }
837 +                    catch(InterruptedException e) {
838 +                        threadUnexpectedException();
839 +                    }
840 +                }
841 +            });
842 +
843 +        try {
844 +            t1.start();
845 +            Thread.sleep(SHORT_DELAY_MS);
846 +            t2.start();
847 +            Thread.sleep(SHORT_DELAY_MS);
848 +            sync.acquire(1);
849 +            assertTrue(sync.hasWaiters(c));
850 +            assertEquals(2, sync.getWaitQueueLength(c));
851 +            c.signalAll();
852 +            sync.release(1);
853 +            Thread.sleep(SHORT_DELAY_MS);
854 +            sync.acquire(1);
855 +            assertFalse(sync.hasWaiters(c));
856 +            assertEquals(0, sync.getWaitQueueLength(c));
857 +            sync.release(1);
858 +            t1.join(SHORT_DELAY_MS);
859 +            t2.join(SHORT_DELAY_MS);
860 +            assertFalse(t1.isAlive());
861 +            assertFalse(t2.isAlive());
862 +        }
863 +        catch (Exception ex) {
864 +            unexpectedException();
865 +        }
866 +    }
867 +
868 +    /**
869 +     * getWaitingThreads returns only and all waiting threads
870 +     */
871 +    public void testGetWaitingThreads() {
872 +        final Mutex sync = new Mutex();
873 +        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
874 +        Thread t1 = new Thread(new Runnable() {
875 +                public void run() {
876 +                    try {
877 +                        sync.acquire(1);
878 +                        threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
879 +                        c.await();
880 +                        sync.release(1);
881 +                    }
882 +                    catch(InterruptedException e) {
883 +                        threadUnexpectedException();
884 +                    }
885 +                }
886 +            });
887 +
888 +        Thread t2 = new Thread(new Runnable() {
889 +                public void run() {
890 +                    try {
891 +                        sync.acquire(1);
892 +                        threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
893 +                        c.await();
894 +                        sync.release(1);
895 +                    }
896 +                    catch(InterruptedException e) {
897 +                        threadUnexpectedException();
898 +                    }
899 +                }
900 +            });
901 +
902 +        try {
903 +            sync.acquire(1);
904 +            assertTrue(sync.getWaitingThreads(c).isEmpty());
905 +            sync.release(1);
906 +            t1.start();
907 +            Thread.sleep(SHORT_DELAY_MS);
908 +            t2.start();
909 +            Thread.sleep(SHORT_DELAY_MS);
910 +            sync.acquire(1);
911 +            assertTrue(sync.hasWaiters(c));
912 +            assertTrue(sync.getWaitingThreads(c).contains(t1));
913 +            assertTrue(sync.getWaitingThreads(c).contains(t2));
914 +            c.signalAll();
915 +            sync.release(1);
916 +            Thread.sleep(SHORT_DELAY_MS);
917 +            sync.acquire(1);
918 +            assertFalse(sync.hasWaiters(c));
919 +            assertTrue(sync.getWaitingThreads(c).isEmpty());
920 +            sync.release(1);
921 +            t1.join(SHORT_DELAY_MS);
922 +            t2.join(SHORT_DELAY_MS);
923 +            assertFalse(t1.isAlive());
924 +            assertFalse(t2.isAlive());
925 +        }
926 +        catch (Exception ex) {
927 +            unexpectedException();
928 +        }
929 +    }
930 +
931 +
932 +
933 +    /**
934 +     * awaitUninterruptibly doesn't abort on interrupt
935 +     */
936 +    public void testAwaitUninterruptibly() {
937 +        final Mutex sync = new Mutex();
938 +        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
939 +        Thread t = new Thread(new Runnable() {
940 +                public void run() {
941 +                    sync.acquire(1);
942 +                    c.awaitUninterruptibly();
943 +                    sync.release(1);
944 +                }
945 +            });
946 +
947 +        try {
948 +            t.start();
949 +            Thread.sleep(SHORT_DELAY_MS);
950 +            t.interrupt();
951 +            sync.acquire(1);
952 +            c.signal();
953 +            sync.release(1);
954 +            t.join(SHORT_DELAY_MS);
955 +            assertFalse(t.isAlive());
956 +        }
957 +        catch (Exception ex) {
958 +            unexpectedException();
959 +        }
960 +    }
961 +
962 +    /**
963 +     * await is interruptible
964 +     */
965 +    public void testAwait_Interrupt() {
966 +        final Mutex sync = new Mutex();
967 +        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
968 +        Thread t = new Thread(new Runnable() {
969 +                public void run() {
970 +                    try {
971 +                        sync.acquire(1);
972 +                        c.await();
973 +                        sync.release(1);
974 +                        threadShouldThrow();
975 +                    }
976 +                    catch(InterruptedException success) {
977 +                    }
978 +                }
979 +            });
980 +
981 +        try {
982 +            t.start();
983 +            Thread.sleep(SHORT_DELAY_MS);
984 +            t.interrupt();
985 +            t.join(SHORT_DELAY_MS);
986 +            assertFalse(t.isAlive());
987 +        }
988 +        catch (Exception ex) {
989 +            unexpectedException();
990 +        }
991 +    }
992 +
993 +    /**
994 +     * awaitNanos is interruptible
995 +     */
996 +    public void testAwaitNanos_Interrupt() {
997 +        final Mutex sync = new Mutex();
998 +        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
999 +        Thread t = new Thread(new Runnable() {
1000 +                public void run() {
1001 +                    try {
1002 +                        sync.acquire(1);
1003 +                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
1004 +                        sync.release(1);
1005 +                        threadShouldThrow();
1006 +                    }
1007 +                    catch(InterruptedException success) {
1008 +                    }
1009 +                }
1010 +            });
1011 +
1012 +        try {
1013 +            t.start();
1014 +            Thread.sleep(SHORT_DELAY_MS);
1015 +            t.interrupt();
1016 +            t.join(SHORT_DELAY_MS);
1017 +            assertFalse(t.isAlive());
1018 +        }
1019 +        catch (Exception ex) {
1020 +            unexpectedException();
1021 +        }
1022 +    }
1023 +
1024 +    /**
1025 +     * awaitUntil is interruptible
1026 +     */
1027 +    public void testAwaitUntil_Interrupt() {
1028 +        final Mutex sync = new Mutex();
1029 +        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
1030 +        Thread t = new Thread(new Runnable() {
1031 +                public void run() {
1032 +                    try {
1033 +                        sync.acquire(1);
1034 +                        java.util.Date d = new java.util.Date();
1035 +                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1036 +                        sync.release(1);
1037 +                        threadShouldThrow();
1038 +                    }
1039 +                    catch(InterruptedException success) {
1040 +                    }
1041 +                }
1042 +            });
1043 +
1044 +        try {
1045 +            t.start();
1046 +            Thread.sleep(SHORT_DELAY_MS);
1047 +            t.interrupt();
1048 +            t.join(SHORT_DELAY_MS);
1049 +            assertFalse(t.isAlive());
1050 +        }
1051 +        catch (Exception ex) {
1052 +            unexpectedException();
1053 +        }
1054 +    }
1055 +
1056 +    /**
1057 +     * signalAll wakes up all threads
1058 +     */
1059 +    public void testSignalAll() {
1060 +        final Mutex sync = new Mutex();
1061 +        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
1062 +        Thread t1 = new Thread(new Runnable() {
1063 +                public void run() {
1064 +                    try {
1065 +                        sync.acquire(1);
1066 +                        c.await();
1067 +                        sync.release(1);
1068 +                    }
1069 +                    catch(InterruptedException e) {
1070 +                        threadUnexpectedException();
1071 +                    }
1072 +                }
1073 +            });
1074 +
1075 +        Thread t2 = new Thread(new Runnable() {
1076 +                public void run() {
1077 +                    try {
1078 +                        sync.acquire(1);
1079 +                        c.await();
1080 +                        sync.release(1);
1081 +                    }
1082 +                    catch(InterruptedException e) {
1083 +                        threadUnexpectedException();
1084 +                    }
1085 +                }
1086 +            });
1087 +
1088 +        try {
1089 +            t1.start();
1090 +            t2.start();
1091 +            Thread.sleep(SHORT_DELAY_MS);
1092 +            sync.acquire(1);
1093 +            c.signalAll();
1094 +            sync.release(1);
1095 +            t1.join(SHORT_DELAY_MS);
1096 +            t2.join(SHORT_DELAY_MS);
1097 +            assertFalse(t1.isAlive());
1098 +            assertFalse(t2.isAlive());
1099 +        }
1100 +        catch (Exception ex) {
1101 +            unexpectedException();
1102 +        }
1103 +    }
1104 +
1105 +
1106 +    /**
1107 +     * toString indicates current state
1108 +     */
1109 +    public void testToString() {
1110 +        Mutex sync = new Mutex();
1111 +        String us = sync.toString();
1112 +        assertTrue(us.indexOf("State = 0") >= 0);
1113 +        sync.acquire(1);
1114 +        String ls = sync.toString();
1115 +        assertTrue(ls.indexOf("State = 1") >= 0);
1116 +    }
1117 +
1118 +    /**
1119 +     * A serialized AQS deserializes with current state
1120 +     */
1121 +    public void testSerialization() {
1122 +        Mutex l = new Mutex();
1123 +        l.acquire(1);
1124 +        assertTrue(l.isHeldExclusively());
1125 +
1126 +        try {
1127 +            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
1128 +            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
1129 +            out.writeObject(l);
1130 +            out.close();
1131 +
1132 +            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
1133 +            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
1134 +            Mutex r = (Mutex) in.readObject();
1135 +            assertTrue(r.isHeldExclusively());
1136 +        } catch(Exception e){
1137 +            e.printStackTrace();
1138 +            unexpectedException();
1139 +        }
1140 +    }
1141 +
1142 +
1143 +    /**
1144 +     * tryReleaseShared setting state changes getState
1145 +     */
1146 +    public void testGetStateWithReleaseShared() {
1147 +        final BooleanLatch l = new BooleanLatch();
1148 +        assertFalse(l.isSignalled());
1149 +        l.releaseShared(0);
1150 +        assertTrue(l.isSignalled());
1151 +    }
1152 +
1153 +    /**
1154 +     * releaseShared has no effect when already signalled
1155 +     */
1156 +    public void testReleaseShared() {
1157 +        final BooleanLatch l = new BooleanLatch();
1158 +        assertFalse(l.isSignalled());
1159 +        l.releaseShared(0);
1160 +        assertTrue(l.isSignalled());
1161 +        l.releaseShared(0);
1162 +        assertTrue(l.isSignalled());
1163 +    }
1164 +
1165 +    /**
1166 +     * acquireSharedInterruptibly returns after release, but not before
1167 +     */
1168 +    public void testAcquireSharedInterruptibly() {
1169 +        final BooleanLatch l = new BooleanLatch();
1170 +
1171 +        Thread t = new Thread(new Runnable() {
1172 +                public void run() {
1173 +                    try {
1174 +                        threadAssertFalse(l.isSignalled());
1175 +                        l.acquireSharedInterruptibly(0);
1176 +                        threadAssertTrue(l.isSignalled());
1177 +                    } catch(InterruptedException e){
1178 +                        threadUnexpectedException();
1179 +                    }
1180 +                }
1181 +            });
1182 +        try {
1183 +            t.start();
1184 +            assertFalse(l.isSignalled());
1185 +            Thread.sleep(SHORT_DELAY_MS);
1186 +            l.releaseShared(0);
1187 +            assertTrue(l.isSignalled());
1188 +            t.join();
1189 +        } catch (InterruptedException e){
1190 +            unexpectedException();
1191 +        }
1192 +    }
1193 +    
1194 +
1195 +    /**
1196 +     * acquireSharedTimed returns after release
1197 +     */
1198 +    public void testAsquireSharedTimed() {
1199 +        final BooleanLatch l = new BooleanLatch();
1200 +
1201 +        Thread t = new Thread(new Runnable() {
1202 +                public void run() {
1203 +                    try {
1204 +                        threadAssertFalse(l.isSignalled());
1205 +                        threadAssertTrue(l.tryAcquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
1206 +                        threadAssertTrue(l.isSignalled());
1207 +
1208 +                    } catch(InterruptedException e){
1209 +                        threadUnexpectedException();
1210 +                    }
1211 +                }
1212 +            });
1213 +        try {
1214 +            t.start();
1215 +            assertFalse(l.isSignalled());
1216 +            Thread.sleep(SHORT_DELAY_MS);
1217 +            l.releaseShared(0);
1218 +            assertTrue(l.isSignalled());
1219 +            t.join();
1220 +        } catch (InterruptedException e){
1221 +            unexpectedException();
1222 +        }
1223 +    }
1224 +    
1225 +    /**
1226 +     * acquireSharedInterruptibly throws IE if interrupted before released
1227 +     */
1228 +    public void testAcquireSharedInterruptibly_InterruptedException() {
1229 +        final BooleanLatch l = new BooleanLatch();
1230 +        Thread t = new Thread(new Runnable() {
1231 +                public void run() {
1232 +                    try {
1233 +                        threadAssertFalse(l.isSignalled());
1234 +                        l.acquireSharedInterruptibly(0);
1235 +                        threadShouldThrow();
1236 +                    } catch(InterruptedException success){}
1237 +                }
1238 +            });
1239 +        t.start();
1240 +        try {
1241 +            assertFalse(l.isSignalled());
1242 +            t.interrupt();
1243 +            t.join();
1244 +        } catch (InterruptedException e){
1245 +            unexpectedException();
1246 +        }
1247 +    }
1248 +
1249 +    /**
1250 +     * acquireSharedTimed throws IE if interrupted before released
1251 +     */
1252 +    public void testAcquireSharedNanos_InterruptedException() {
1253 +        final BooleanLatch l = new BooleanLatch();
1254 +        Thread t = new Thread(new Runnable() {
1255 +                public void run() {
1256 +                    try {
1257 +                        threadAssertFalse(l.isSignalled());
1258 +                        l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
1259 +                        threadShouldThrow();                        
1260 +                    } catch(InterruptedException success){}
1261 +                }
1262 +            });
1263 +        t.start();
1264 +        try {
1265 +            Thread.sleep(SHORT_DELAY_MS);
1266 +            assertFalse(l.isSignalled());
1267 +            t.interrupt();
1268 +            t.join();
1269 +        } catch (InterruptedException e){
1270 +            unexpectedException();
1271 +        }
1272 +    }
1273 +
1274 +    /**
1275 +     * acquireSharedTimed times out if not released before timeout
1276 +     */
1277 +    public void testAcquireSharedNanos_Timeout() {
1278 +        final BooleanLatch l = new BooleanLatch();
1279 +        Thread t = new Thread(new Runnable() {
1280 +                public void run() {
1281 +                    try {
1282 +                        threadAssertFalse(l.isSignalled());
1283 +                        threadAssertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
1284 +                    } catch(InterruptedException ie){
1285 +                        threadUnexpectedException();
1286 +                    }
1287 +                }
1288 +            });
1289 +        t.start();
1290 +        try {
1291 +            Thread.sleep(SHORT_DELAY_MS);
1292 +            assertFalse(l.isSignalled());
1293 +            t.join();
1294 +        } catch (InterruptedException e){
1295 +            unexpectedException();
1296 +        }
1297 +    }
1298 +
1299      
1300   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines