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

Comparing jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java (file contents):
Revision 1.7 by dl, Fri Jan 2 21:06:38 2004 UTC vs.
Revision 1.14 by dl, Sat Jan 10 01:41:59 2004 UTC

# Line 22 | Line 22 | public class AbstractQueuedSynchronizerT
22      }
23  
24      /**
25 <     * A simple mutex class, from the AbstractQueuedSynchronizer
26 <     * javadoc.  All tests exercise this as a sample user extension.
27 <     * Other methods/features of AbstractQueuedSynchronizerTest are
28 <     * tested implicitly in ReentrantLock, ReentrantReadWriteLock, and
29 <     * Semaphore test classes
30 <     */
31 <    static class Mutex implements Lock, java.io.Serializable {
32 <        private static class Sync extends AbstractQueuedSynchronizer {
33 <            boolean isLocked() { return getState() == 1; }
34 <
35 <            public boolean tryAcquireExclusive(boolean isQueued, int acquires) {
36 <                assert acquires == 1; // Does not use multiple acquires
37 <                return compareAndSetState(0, 1);
38 <            }
39 <            
40 <            public boolean tryReleaseExclusive(int releases) {
41 <                setState(0);
42 <                return true;
43 <            }
44 <            
45 <            public void checkConditionAccess(Thread thread, boolean waiting) {
46 <                if (getState() == 0) throw new IllegalMonitorStateException();
47 <            }
48 <            
49 <            Condition newCondition() { return new ConditionObject(); }
50 <            
51 <            private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
52 <                s.defaultReadObject();
53 <                setState(0); // reset to unlocked state
54 <            }
55 <        }
56 <        
57 <        private final Sync sync = new Sync();
58 <        public boolean tryLock() {
59 <            return sync.tryAcquireExclusive(false, 1);
60 <        }
25 >     * A simple mutex class, adapted from the
26 >     * AbstractQueuedSynchronizer javadoc.  Exclusive acquire tests
27 >     * exercise this as a sample user extension.  Other
28 >     * methods/features of AbstractQueuedSynchronizerTest are tested
29 >     * via other test classes, including those for ReentrantLock,
30 >     * ReentrantReadWriteLock, and Semaphore
31 >     */
32 >    static class Mutex extends AbstractQueuedSynchronizer {
33 >        public boolean isLocked() { return getState() == 1; }
34 >        
35 >        public boolean tryAcquireExclusive(int acquires) {
36 >            assertTrue(acquires == 1);
37 >            return compareAndSetState(0, 1);
38 >        }
39 >        
40 >        public boolean tryReleaseExclusive(int releases) {
41 >            setState(0);
42 >            return true;
43 >        }
44 >        
45 >        public void checkConditionAccess(Thread thread) {
46 >            if (getState() == 0) throw new IllegalMonitorStateException();
47 >        }
48 >        
49 >        public ConditionObject newCondition() { return new ConditionObject(); }
50 >        
51          public void lock() {
52 <            sync.acquireExclusiveUninterruptibly(1);
52 >            acquireExclusiveUninterruptibly(1);
53          }
54 <        public void lockInterruptibly() throws InterruptedException {
55 <            sync.acquireExclusiveInterruptibly(1);
54 >
55 >    }
56 >
57 >    
58 >    /**
59 >     * A simple latch class, to test shared mode.
60 >     */
61 >    static class BooleanLatch extends AbstractQueuedSynchronizer {
62 >        public boolean isSignalled() { return getState() != 0; }
63 >
64 >        public int tryAcquireShared(int ignore) {
65 >            return isSignalled()? 1 : -1;
66          }
67 <        public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
68 <            return sync.acquireExclusiveTimed(1, unit.toNanos(timeout));
67 >        
68 >        public boolean tryReleaseShared(int ignore) {
69 >            setState(1);
70 >            return true;
71          }
70        public void unlock() { sync.releaseExclusive(1); }
71        public Condition newCondition() { return sync.newCondition(); }
72        public boolean isLocked() { return sync.isLocked(); }
73        public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
72      }
73  
74      /**
75 <     * A runnable calling lockInterruptibly
75 >     * A runnable calling acquireExclusiveInterruptibly
76       */
77      class InterruptibleLockRunnable implements Runnable {
78          final Mutex lock;
79          InterruptibleLockRunnable(Mutex l) { lock = l; }
80          public void run() {
81              try {
82 <                lock.lockInterruptibly();
82 >                lock.acquireExclusiveInterruptibly(1);
83              } catch(InterruptedException success){}
84          }
85      }
86  
87  
88      /**
89 <     * A runnable calling lockInterruptibly that expects to be
89 >     * A runnable calling acquireExclusiveInterruptibly that expects to be
90       * interrupted
91       */
92      class InterruptedLockRunnable implements Runnable {
# Line 96 | Line 94 | public class AbstractQueuedSynchronizerT
94          InterruptedLockRunnable(Mutex l) { lock = l; }
95          public void run() {
96              try {
97 <                lock.lockInterruptibly();
97 >                lock.acquireExclusiveInterruptibly(1);
98                  threadShouldThrow();
99              } catch(InterruptedException success){}
100          }
101      }
102      
103      /**
104 <     * locking an unlocked lock succeeds
104 >     * acquireExclusiveUninterruptiblying an releaseExclusiveed lock succeeds
105       */
106 <    public void testLock() {
106 >    public void testAcquireExclusiveUninterruptibly() {
107          Mutex rl = new Mutex();
108 <        rl.lock();
108 >        rl.acquireExclusiveUninterruptibly(1);
109          assertTrue(rl.isLocked());
110 <        rl.unlock();
110 >        rl.releaseExclusive(1);
111      }
112  
113      /**
114 <     * tryLock on an unlocked lock succeeds
114 >     * tryAcquireExclusive on an releaseExclusiveed lock succeeds
115       */
116 <    public void testTryLock() {
116 >    public void testTryAcquireExclusive() {
117          Mutex rl = new Mutex();
118 <        assertTrue(rl.tryLock());
118 >        assertTrue(rl.tryAcquireExclusive(1));
119          assertTrue(rl.isLocked());
120 <        rl.unlock();
120 >        rl.releaseExclusive(1);
121      }
122  
123      /**
# Line 131 | Line 129 | public class AbstractQueuedSynchronizerT
129          Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
130          try {
131              assertFalse(lock.hasQueuedThreads());
132 <            lock.lock();
132 >            lock.acquireExclusiveUninterruptibly(1);
133              t1.start();
134              Thread.sleep(SHORT_DELAY_MS);
135              assertTrue(lock.hasQueuedThreads());
# Line 141 | Line 139 | public class AbstractQueuedSynchronizerT
139              t1.interrupt();
140              Thread.sleep(SHORT_DELAY_MS);
141              assertTrue(lock.hasQueuedThreads());
142 <            lock.unlock();
142 >            lock.releaseExclusive(1);
143              Thread.sleep(SHORT_DELAY_MS);
144              assertFalse(lock.hasQueuedThreads());
145              t1.join();
# Line 152 | Line 150 | public class AbstractQueuedSynchronizerT
150      }
151  
152      /**
153 <     * timed tryLock is interruptible.
153 >     * isQueued(null) throws NPE
154 >     */
155 >    public void testIsQueuedNPE() {
156 >        final Mutex lock = new Mutex();
157 >        try {
158 >            lock.isQueued(null);
159 >            shouldThrow();
160 >        } catch (NullPointerException success) {
161 >        }
162 >    }
163 >
164 >    /**
165 >     * isQueued reports whether a thread is queued.
166 >     */
167 >    public void testIsQueued() {
168 >        final Mutex lock = new Mutex();
169 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
170 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
171 >        try {
172 >            assertFalse(lock.isQueued(t1));
173 >            assertFalse(lock.isQueued(t2));
174 >            lock.acquireExclusiveUninterruptibly(1);
175 >            t1.start();
176 >            Thread.sleep(SHORT_DELAY_MS);
177 >            assertTrue(lock.isQueued(t1));
178 >            t2.start();
179 >            Thread.sleep(SHORT_DELAY_MS);
180 >            assertTrue(lock.isQueued(t1));
181 >            assertTrue(lock.isQueued(t2));
182 >            t1.interrupt();
183 >            Thread.sleep(SHORT_DELAY_MS);
184 >            assertFalse(lock.isQueued(t1));
185 >            assertTrue(lock.isQueued(t2));
186 >            lock.releaseExclusive(1);
187 >            Thread.sleep(SHORT_DELAY_MS);
188 >            assertFalse(lock.isQueued(t1));
189 >            assertFalse(lock.isQueued(t2));
190 >            t1.join();
191 >            t2.join();
192 >        } catch(Exception e){
193 >            unexpectedException();
194 >        }
195 >    }
196 >
197 >    /**
198 >     * getFirstQueuedThread returns first waiting thread or null is none
199 >     */
200 >    public void testGetFirstQueuedThread() {
201 >        final Mutex lock = new Mutex();
202 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
203 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
204 >        try {
205 >            assertNull(lock.getFirstQueuedThread());
206 >            lock.acquireExclusiveUninterruptibly(1);
207 >            t1.start();
208 >            Thread.sleep(SHORT_DELAY_MS);
209 >            assertEquals(t1, lock.getFirstQueuedThread());
210 >            t2.start();
211 >            Thread.sleep(SHORT_DELAY_MS);
212 >            assertEquals(t1, lock.getFirstQueuedThread());
213 >            t1.interrupt();
214 >            Thread.sleep(SHORT_DELAY_MS);
215 >            assertEquals(t2, lock.getFirstQueuedThread());
216 >            lock.releaseExclusive(1);
217 >            Thread.sleep(SHORT_DELAY_MS);
218 >            assertNull(lock.getFirstQueuedThread());
219 >            t1.join();
220 >            t2.join();
221 >        } catch(Exception e){
222 >            unexpectedException();
223 >        }
224 >    }
225 >
226 >
227 >    /**
228 >     * hasContended reports false if no thread has ever blocked, else true
229 >     */
230 >    public void testHasContended() {
231 >        final Mutex lock = new Mutex();
232 >        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
233 >        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
234 >        try {
235 >            assertFalse(lock.hasContended());
236 >            lock.acquireExclusiveUninterruptibly(1);
237 >            t1.start();
238 >            Thread.sleep(SHORT_DELAY_MS);
239 >            assertTrue(lock.hasContended());
240 >            t2.start();
241 >            Thread.sleep(SHORT_DELAY_MS);
242 >            assertTrue(lock.hasContended());
243 >            t1.interrupt();
244 >            Thread.sleep(SHORT_DELAY_MS);
245 >            assertTrue(lock.hasContended());
246 >            lock.releaseExclusive(1);
247 >            Thread.sleep(SHORT_DELAY_MS);
248 >            assertTrue(lock.hasContended());
249 >            t1.join();
250 >            t2.join();
251 >        } catch(Exception e){
252 >            unexpectedException();
253 >        }
254 >    }
255 >
256 >    /**
257 >     * acquireExclusiveNanos is interruptible.
258       */
259      public void testInterruptedException2() {
260          final Mutex lock = new Mutex();
261 <        lock.lock();
261 >        lock.acquireExclusiveUninterruptibly(1);
262          Thread t = new Thread(new Runnable() {
263                  public void run() {
264                      try {
265 <                        lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS);
265 >                        lock.acquireExclusiveNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
266                          threadShouldThrow();
267                      } catch(InterruptedException success){}
268                  }
# Line 175 | Line 277 | public class AbstractQueuedSynchronizerT
277  
278  
279      /**
280 <     * TryLock on a locked lock fails
280 >     * TryAcquireExclusive on a locked lock fails
281       */
282 <    public void testTryLockWhenLocked() {
282 >    public void testTryAcquireExclusiveWhenLocked() {
283          final Mutex lock = new Mutex();
284 <        lock.lock();
284 >        lock.acquireExclusiveUninterruptibly(1);
285          Thread t = new Thread(new Runnable() {
286                  public void run() {
287 <                    threadAssertFalse(lock.tryLock());
287 >                    threadAssertFalse(lock.tryAcquireExclusive(1));
288                  }
289              });
290          try {
291              t.start();
292              t.join();
293 <            lock.unlock();
293 >            lock.releaseExclusive(1);
294          } catch(Exception e){
295              unexpectedException();
296          }
297      }
298  
299      /**
300 <     * Timed tryLock on a locked lock times out
300 >     * acquireExclusiveNanos on a locked lock times out
301       */
302 <    public void testTryLock_Timeout() {
302 >    public void testAcquireExclusiveNanos_Timeout() {
303          final Mutex lock = new Mutex();
304 <        lock.lock();
304 >        lock.acquireExclusiveUninterruptibly(1);
305          Thread t = new Thread(new Runnable() {
306                  public void run() {
307                      try {
308 <                        threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS));
308 >                        threadAssertFalse(lock.acquireExclusiveNanos(1, 1000 * 1000));
309                      } catch (Exception ex) {
310                          threadUnexpectedException();
311                      }
# Line 212 | Line 314 | public class AbstractQueuedSynchronizerT
314          try {
315              t.start();
316              t.join();
317 <            lock.unlock();
317 >            lock.releaseExclusive(1);
318          } catch(Exception e){
319              unexpectedException();
320          }
# Line 220 | Line 322 | public class AbstractQueuedSynchronizerT
322      
323    
324      /**
325 <     * isLocked is true when locked and false when not
325 >     * getState is true when acquired and false when not
326       */
327 <    public void testIsLocked() {
327 >    public void testGetState() {
328          final Mutex lock = new Mutex();
329 <        lock.lock();
329 >        lock.acquireExclusiveUninterruptibly(1);
330          assertTrue(lock.isLocked());
331 <        lock.unlock();
331 >        lock.releaseExclusive(1);
332          assertFalse(lock.isLocked());
333          Thread t = new Thread(new Runnable() {
334                  public void run() {
335 <                    lock.lock();
335 >                    lock.acquireExclusiveUninterruptibly(1);
336                      try {
337                          Thread.sleep(SMALL_DELAY_MS);
338                      }
339                      catch(Exception e) {
340                          threadUnexpectedException();
341                      }
342 <                    lock.unlock();
342 >                    lock.releaseExclusive(1);
343                  }
344              });
345          try {
# Line 253 | Line 355 | public class AbstractQueuedSynchronizerT
355  
356  
357      /**
358 <     * lockInterruptibly is interruptible.
358 >     * acquireExclusiveInterruptibly is interruptible.
359       */
360 <    public void testLockInterruptibly1() {
360 >    public void testAcquireInterruptibly1() {
361          final Mutex lock = new Mutex();
362 <        lock.lock();
362 >        lock.acquireExclusiveUninterruptibly(1);
363          Thread t = new Thread(new InterruptedLockRunnable(lock));
364          try {
365              t.start();
366              t.interrupt();
367 <            lock.unlock();
367 >            lock.releaseExclusive(1);
368              t.join();
369          } catch(Exception e){
370              unexpectedException();
# Line 270 | Line 372 | public class AbstractQueuedSynchronizerT
372      }
373  
374      /**
375 <     * lockInterruptibly succeeds when unlocked, else is interruptible
375 >     * acquireExclusiveInterruptibly succeeds when released, else is interruptible
376       */
377 <    public void testLockInterruptibly2() {
377 >    public void testAcquireInterruptibly2() {
378          final Mutex lock = new Mutex();
379          try {
380 <            lock.lockInterruptibly();
380 >            lock.acquireExclusiveInterruptibly(1);
381          } catch(Exception e) {
382              unexpectedException();
383          }
# Line 291 | Line 393 | public class AbstractQueuedSynchronizerT
393      }
394  
395      /**
396 +     * owns is true for a condition created by lock else false
397 +     */
398 +    public void testOwns() {
399 +        final Mutex lock = new Mutex();
400 +        final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
401 +        final Mutex lock2 = new Mutex();
402 +        assertTrue(lock.owns(c));
403 +        assertFalse(lock2.owns(c));
404 +    }
405 +
406 +    /**
407       * Calling await without holding lock throws IllegalMonitorStateException
408       */
409      public void testAwait_IllegalMonitor() {
# Line 331 | Line 444 | public class AbstractQueuedSynchronizerT
444          final Mutex lock = new Mutex();
445          final Condition 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 348 | Line 461 | public class AbstractQueuedSynchronizerT
461          final Mutex lock = new Mutex();
462          final Condition 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 364 | Line 477 | public class AbstractQueuedSynchronizerT
477          final Mutex lock = new Mutex();
478          final Condition 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 383 | Line 496 | public class AbstractQueuedSynchronizerT
496          Thread t = new Thread(new Runnable() {
497                  public void run() {
498                      try {
499 <                        lock.lock();
499 >                        lock.acquireExclusiveUninterruptibly(1);
500                          c.await();
501 <                        lock.unlock();
501 >                        lock.releaseExclusive(1);
502                      }
503                      catch(InterruptedException e) {
504                          threadUnexpectedException();
# Line 396 | Line 509 | public class AbstractQueuedSynchronizerT
509          try {
510              t.start();
511              Thread.sleep(SHORT_DELAY_MS);
512 <            lock.lock();
512 >            lock.acquireExclusiveUninterruptibly(1);
513              c.signal();
514 <            lock.unlock();
514 >            lock.releaseExclusive(1);
515              t.join(SHORT_DELAY_MS);
516              assertFalse(t.isAlive());
517          }
# Line 406 | Line 519 | public class AbstractQueuedSynchronizerT
519              unexpectedException();
520          }
521      }
522 +
523 +    /**
524 +     * toString indicates current state
525 +     */
526 +    public void testToString() {
527 +        Mutex lock = new Mutex();
528 +        String us = lock.toString();
529 +        assertTrue(us.indexOf("State = 0") >= 0);
530 +        lock.acquireExclusiveUninterruptibly(1);
531 +        String ls = lock.toString();
532 +        assertTrue(ls.indexOf("State = 1") >= 0);
533 +    }
534 +
535 +    /**
536 +     * A serialized AQS deserializes with current state
537 +     */
538 +    public void testSerialization() {
539 +        Mutex l = new Mutex();
540 +        l.acquireExclusiveUninterruptibly(1);
541 +        assertTrue(l.isLocked());
542 +
543 +        try {
544 +            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
545 +            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
546 +            out.writeObject(l);
547 +            out.close();
548 +
549 +            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
550 +            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
551 +            Mutex r = (Mutex) in.readObject();
552 +            assertTrue(r.isLocked());
553 +        } catch(Exception e){
554 +            e.printStackTrace();
555 +            unexpectedException();
556 +        }
557 +    }
558 +
559 +
560 +    /**
561 +     * Latch isSignalled initially returns false, then true after release
562 +     */
563 +    public void testLatchIsSignalled() {
564 +        final BooleanLatch l = new BooleanLatch();
565 +        assertFalse(l.isSignalled());
566 +        l.releaseShared(0);
567 +        assertTrue(l.isSignalled());
568 +    }
569 +
570 +    /**
571 +     * release and has no effect when already signalled
572 +     */
573 +    public void testReleaseShared() {
574 +        final BooleanLatch l = new BooleanLatch();
575 +        assertFalse(l.isSignalled());
576 +        l.releaseShared(0);
577 +        assertTrue(l.isSignalled());
578 +        l.releaseShared(0);
579 +        assertTrue(l.isSignalled());
580 +    }
581 +
582 +    /**
583 +     * acquireSharedInterruptibly returns after release, but not before
584 +     */
585 +    public void testAcquireSharedInterruptibly() {
586 +        final BooleanLatch l = new BooleanLatch();
587 +
588 +        Thread t = new Thread(new Runnable() {
589 +                public void run() {
590 +                    try {
591 +                        threadAssertFalse(l.isSignalled());
592 +                        l.acquireSharedInterruptibly(0);
593 +                        threadAssertTrue(l.isSignalled());
594 +                    } catch(InterruptedException e){
595 +                        threadUnexpectedException();
596 +                    }
597 +                }
598 +            });
599 +        try {
600 +            t.start();
601 +            assertFalse(l.isSignalled());
602 +            Thread.sleep(SHORT_DELAY_MS);
603 +            l.releaseShared(0);
604 +            assertTrue(l.isSignalled());
605 +            t.join();
606 +        } catch (InterruptedException e){
607 +            unexpectedException();
608 +        }
609 +    }
610 +    
611 +
612 +    /**
613 +     * acquireSharedTimed returns after release
614 +     */
615 +    public void testAsquireSharedTimed() {
616 +        final BooleanLatch l = new BooleanLatch();
617 +
618 +        Thread t = new Thread(new Runnable() {
619 +                public void run() {
620 +                    try {
621 +                        threadAssertFalse(l.isSignalled());
622 +                        threadAssertTrue(l.acquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
623 +                        threadAssertTrue(l.isSignalled());
624 +
625 +                    } catch(InterruptedException e){
626 +                        threadUnexpectedException();
627 +                    }
628 +                }
629 +            });
630 +        try {
631 +            t.start();
632 +            assertFalse(l.isSignalled());
633 +            Thread.sleep(SHORT_DELAY_MS);
634 +            l.releaseShared(0);
635 +            assertTrue(l.isSignalled());
636 +            t.join();
637 +        } catch (InterruptedException e){
638 +            unexpectedException();
639 +        }
640 +    }
641 +    
642 +    /**
643 +     * acquireSharedInterruptibly throws IE if interrupted before released
644 +     */
645 +    public void testAcquireSharedInterruptibly_InterruptedException() {
646 +        final BooleanLatch l = new BooleanLatch();
647 +        Thread t = new Thread(new Runnable() {
648 +                public void run() {
649 +                    try {
650 +                        threadAssertFalse(l.isSignalled());
651 +                        l.acquireSharedInterruptibly(0);
652 +                        threadShouldThrow();
653 +                    } catch(InterruptedException success){}
654 +                }
655 +            });
656 +        t.start();
657 +        try {
658 +            assertFalse(l.isSignalled());
659 +            t.interrupt();
660 +            t.join();
661 +        } catch (InterruptedException e){
662 +            unexpectedException();
663 +        }
664 +    }
665 +
666 +    /**
667 +     * acquireSharedTimed throws IE if interrupted before released
668 +     */
669 +    public void testAcquireSharedNanos_InterruptedException() {
670 +        final BooleanLatch l = new BooleanLatch();
671 +        Thread t = new Thread(new Runnable() {
672 +                public void run() {
673 +                    try {
674 +                        threadAssertFalse(l.isSignalled());
675 +                        l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
676 +                        threadShouldThrow();                        
677 +                    } catch(InterruptedException success){}
678 +                }
679 +            });
680 +        t.start();
681 +        try {
682 +            Thread.sleep(SHORT_DELAY_MS);
683 +            assertFalse(l.isSignalled());
684 +            t.interrupt();
685 +            t.join();
686 +        } catch (InterruptedException e){
687 +            unexpectedException();
688 +        }
689 +    }
690 +
691 +    /**
692 +     * acquireSharedTimed times out if not released before timeout
693 +     */
694 +    public void testAcquireSharedNanos_Timeout() {
695 +        final BooleanLatch l = new BooleanLatch();
696 +        Thread t = new Thread(new Runnable() {
697 +                public void run() {
698 +                    try {
699 +                        threadAssertFalse(l.isSignalled());
700 +                        threadAssertFalse(l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
701 +                    } catch(InterruptedException ie){
702 +                        threadUnexpectedException();
703 +                    }
704 +                }
705 +            });
706 +        t.start();
707 +        try {
708 +            Thread.sleep(SHORT_DELAY_MS);
709 +            assertFalse(l.isSignalled());
710 +            t.join();
711 +        } catch (InterruptedException e){
712 +            unexpectedException();
713 +        }
714 +    }
715 +
716      
717   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines