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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines