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.2 by dl, Mon Dec 29 01:18:40 2003 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 <            public int acquireExclusiveState(boolean isQueued, int acquires, Thread current) {
34 <                assert acquires == 1; // Does not use multiple acquires
35 <                return state().compareAndSet(0, 1)? 0 : -1;
36 <            }
37 <            
38 <            public boolean releaseExclusiveState(int releases) {
39 <                state().set(0);
40 <                return true;
41 <            }
42 <            
43 <            public int acquireSharedState(boolean isQueued, int acquires, Thread current) {
44 <                throw new UnsupportedOperationException();
45 <            }
46 <            
47 <            public boolean releaseSharedState(int releases) {
48 <                throw new UnsupportedOperationException();
49 <            }
50 <            
51 <            public void checkConditionAccess(Thread thread, boolean waiting) {
52 <                if (state().get() == 0) throw new IllegalMonitorStateException();
53 <            }
54 <            
55 <            Condition newCondition() { return new ConditionObject(); }
56 <            
57 <            private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
58 <                s.defaultReadObject();
59 <                state().set(0); // reset to unlocked state
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 <        private final Sync sync = new Sync();
46 <        public boolean tryLock() {
65 <            return sync.acquireExclusiveState(false, 1, null) >= 0;
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 <            if (!tryLock()) 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          }
76        public void unlock() { sync.releaseExclusive(1); }
77        public Condition newCondition() { return sync.newCondition(); }
78        public boolean isLocked() { return sync.state().get() != 0; }
79        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 102 | 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 137 | 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 147 | 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 158 | 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 181 | 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 218 | 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 226 | 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 259 | 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 276 | 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 297 | 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 318 | 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 335 | 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 352 | 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 368 | 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 385 | 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.acquireExclusiveUninterruptibly(1);
500 >                        c.await();
501 >                        lock.releaseExclusive(1);
502 >                    }
503 >                    catch(InterruptedException e) {
504 >                        threadUnexpectedException();
505 >                    }
506 >                }
507 >            });
508 >
509 >        try {
510 >            t.start();
511 >            Thread.sleep(SHORT_DELAY_MS);
512 >            lock.acquireExclusiveUninterruptibly(1);
513 >            c.signal();
514 >            lock.releaseExclusive(1);
515 >            t.join(SHORT_DELAY_MS);
516 >            assertFalse(t.isAlive());
517 >        }
518 >        catch (Exception ex) {
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.lock();
675 >                        lock.acquireExclusiveUninterruptibly(1);
676 >                        threadAssertFalse(lock.hasWaiters(c));
677 >                        threadAssertEquals(0, lock.getWaitQueueLength(c));
678                          c.await();
679 <                        lock.unlock();
679 >                        lock.releaseExclusive(1);
680                      }
681                      catch(InterruptedException e) {
682                          threadUnexpectedException();
# Line 402 | Line 687 | public class AbstractQueuedSynchronizerT
687          try {
688              t.start();
689              Thread.sleep(SHORT_DELAY_MS);
690 <            lock.lock();
690 >            lock.acquireExclusiveUninterruptibly(1);
691 >            assertTrue(lock.hasWaiters(c));
692 >            assertEquals(1, lock.getWaitQueueLength(c));
693              c.signal();
694 <            lock.unlock();
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          }
# Line 412 | Line 704 | public class AbstractQueuedSynchronizerT
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