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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines