Home | History | Annotate | Download | only in jsr166
      1 /*
      2  * Written by Doug Lea with assistance from members of JCP JSR-166
      3  * Expert Group and released to the public domain, as explained at
      4  * http://creativecommons.org/publicdomain/zero/1.0/
      5  * Other contributors include Andrew Wright, Jeffrey Hayes,
      6  * Pat Fisher, Mike Judd.
      7  */
      8 
      9 package jsr166;
     10 
     11 import junit.framework.*;
     12 import java.util.Arrays;
     13 import java.util.ArrayList;
     14 import java.util.Iterator;
     15 import java.util.NoSuchElementException;
     16 import java.util.concurrent.BlockingQueue;
     17 import java.util.concurrent.CountDownLatch;
     18 import java.util.concurrent.Delayed;
     19 import java.util.concurrent.DelayQueue;
     20 import java.util.concurrent.Executors;
     21 import java.util.concurrent.ExecutorService;
     22 import java.util.concurrent.TimeUnit;
     23 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     24 
     25 public class DelayQueueTest extends BlockingQueueTest {
     26 
     27     protected BlockingQueue emptyCollection() {
     28         return new DelayQueue();
     29     }
     30 
     31     protected PDelay makeElement(int i) {
     32         return new PDelay(i);
     33     }
     34 
     35     private static final int NOCAP = Integer.MAX_VALUE;
     36 
     37     /**
     38      * A delayed implementation for testing.
     39      * Most tests use Pseudodelays, where delays are all elapsed
     40      * (so, no blocking solely for delays) but are still ordered
     41      */
     42     static class PDelay implements Delayed {
     43         int pseudodelay;
     44         PDelay(int i) { pseudodelay = i; }
     45         public int compareTo(PDelay other) {
     46             int a = this.pseudodelay;
     47             int b = other.pseudodelay;
     48             return (a < b) ? -1 : (a > b) ? 1 : 0;
     49         }
     50         public int compareTo(Delayed y) {
     51             return compareTo((PDelay)y);
     52         }
     53         public boolean equals(Object other) {
     54             return (other instanceof PDelay) &&
     55                 this.pseudodelay == ((PDelay)other).pseudodelay;
     56         }
     57         // suppress [overrides] javac warning
     58         public int hashCode() { return pseudodelay; }
     59         public long getDelay(TimeUnit ignore) {
     60             return Integer.MIN_VALUE + pseudodelay;
     61         }
     62         public String toString() {
     63             return String.valueOf(pseudodelay);
     64         }
     65     }
     66 
     67     /**
     68      * Delayed implementation that actually delays
     69      */
     70     static class NanoDelay implements Delayed {
     71         long trigger;
     72         NanoDelay(long i) {
     73             trigger = System.nanoTime() + i;
     74         }
     75         public int compareTo(NanoDelay y) {
     76             long i = trigger;
     77             long j = y.trigger;
     78             if (i < j) return -1;
     79             if (i > j) return 1;
     80             return 0;
     81         }
     82 
     83         public int compareTo(Delayed y) {
     84             return compareTo((NanoDelay)y);
     85         }
     86 
     87         public boolean equals(Object other) {
     88             return equals((NanoDelay)other);
     89         }
     90         public boolean equals(NanoDelay other) {
     91             return other.trigger == trigger;
     92         }
     93 
     94         // suppress [overrides] javac warning
     95         public int hashCode() { return (int) trigger; }
     96 
     97         public long getDelay(TimeUnit unit) {
     98             long n = trigger - System.nanoTime();
     99             return unit.convert(n, TimeUnit.NANOSECONDS);
    100         }
    101 
    102         public long getTriggerTime() {
    103             return trigger;
    104         }
    105 
    106         public String toString() {
    107             return String.valueOf(trigger);
    108         }
    109     }
    110 
    111     /**
    112      * Returns a new queue of given size containing consecutive
    113      * PDelays 0 ... n.
    114      */
    115     private DelayQueue<PDelay> populatedQueue(int n) {
    116         DelayQueue<PDelay> q = new DelayQueue<PDelay>();
    117         assertTrue(q.isEmpty());
    118         for (int i = n-1; i >= 0; i-=2)
    119             assertTrue(q.offer(new PDelay(i)));
    120         for (int i = (n & 1); i < n; i+=2)
    121             assertTrue(q.offer(new PDelay(i)));
    122         assertFalse(q.isEmpty());
    123         assertEquals(NOCAP, q.remainingCapacity());
    124         assertEquals(n, q.size());
    125         return q;
    126     }
    127 
    128     /**
    129      * A new queue has unbounded capacity
    130      */
    131     public void testConstructor1() {
    132         assertEquals(NOCAP, new DelayQueue().remainingCapacity());
    133     }
    134 
    135     /**
    136      * Initializing from null Collection throws NPE
    137      */
    138     public void testConstructor3() {
    139         try {
    140             DelayQueue q = new DelayQueue(null);
    141             shouldThrow();
    142         } catch (NullPointerException success) {}
    143     }
    144 
    145     /**
    146      * Initializing from Collection of null elements throws NPE
    147      */
    148     public void testConstructor4() {
    149         try {
    150             PDelay[] ints = new PDelay[SIZE];
    151             DelayQueue q = new DelayQueue(Arrays.asList(ints));
    152             shouldThrow();
    153         } catch (NullPointerException success) {}
    154     }
    155 
    156     /**
    157      * Initializing from Collection with some null elements throws NPE
    158      */
    159     public void testConstructor5() {
    160         try {
    161             PDelay[] ints = new PDelay[SIZE];
    162             for (int i = 0; i < SIZE-1; ++i)
    163                 ints[i] = new PDelay(i);
    164             DelayQueue q = new DelayQueue(Arrays.asList(ints));
    165             shouldThrow();
    166         } catch (NullPointerException success) {}
    167     }
    168 
    169     /**
    170      * Queue contains all elements of collection used to initialize
    171      */
    172     public void testConstructor6() {
    173         PDelay[] ints = new PDelay[SIZE];
    174         for (int i = 0; i < SIZE; ++i)
    175             ints[i] = new PDelay(i);
    176         DelayQueue q = new DelayQueue(Arrays.asList(ints));
    177         for (int i = 0; i < SIZE; ++i)
    178             assertEquals(ints[i], q.poll());
    179     }
    180 
    181     /**
    182      * isEmpty is true before add, false after
    183      */
    184     public void testEmpty() {
    185         DelayQueue q = new DelayQueue();
    186         assertTrue(q.isEmpty());
    187         assertEquals(NOCAP, q.remainingCapacity());
    188         q.add(new PDelay(1));
    189         assertFalse(q.isEmpty());
    190         q.add(new PDelay(2));
    191         q.remove();
    192         q.remove();
    193         assertTrue(q.isEmpty());
    194     }
    195 
    196     /**
    197      * remainingCapacity does not change when elements added or removed,
    198      * but size does
    199      */
    200     public void testRemainingCapacity() {
    201         DelayQueue q = populatedQueue(SIZE);
    202         for (int i = 0; i < SIZE; ++i) {
    203             assertEquals(NOCAP, q.remainingCapacity());
    204             assertEquals(SIZE-i, q.size());
    205             q.remove();
    206         }
    207         for (int i = 0; i < SIZE; ++i) {
    208             assertEquals(NOCAP, q.remainingCapacity());
    209             assertEquals(i, q.size());
    210             q.add(new PDelay(i));
    211         }
    212     }
    213 
    214     /**
    215      * offer non-null succeeds
    216      */
    217     public void testOffer() {
    218         DelayQueue q = new DelayQueue();
    219         assertTrue(q.offer(new PDelay(0)));
    220         assertTrue(q.offer(new PDelay(1)));
    221     }
    222 
    223     /**
    224      * add succeeds
    225      */
    226     public void testAdd() {
    227         DelayQueue q = new DelayQueue();
    228         for (int i = 0; i < SIZE; ++i) {
    229             assertEquals(i, q.size());
    230             assertTrue(q.add(new PDelay(i)));
    231         }
    232     }
    233 
    234     /**
    235      * addAll(this) throws IAE
    236      */
    237     public void testAddAllSelf() {
    238         try {
    239             DelayQueue q = populatedQueue(SIZE);
    240             q.addAll(q);
    241             shouldThrow();
    242         } catch (IllegalArgumentException success) {}
    243     }
    244 
    245     /**
    246      * addAll of a collection with any null elements throws NPE after
    247      * possibly adding some elements
    248      */
    249     public void testAddAll3() {
    250         try {
    251             DelayQueue q = new DelayQueue();
    252             PDelay[] ints = new PDelay[SIZE];
    253             for (int i = 0; i < SIZE-1; ++i)
    254                 ints[i] = new PDelay(i);
    255             q.addAll(Arrays.asList(ints));
    256             shouldThrow();
    257         } catch (NullPointerException success) {}
    258     }
    259 
    260     /**
    261      * Queue contains all elements of successful addAll
    262      */
    263     public void testAddAll5() {
    264         PDelay[] empty = new PDelay[0];
    265         PDelay[] ints = new PDelay[SIZE];
    266         for (int i = SIZE-1; i >= 0; --i)
    267             ints[i] = new PDelay(i);
    268         DelayQueue q = new DelayQueue();
    269         assertFalse(q.addAll(Arrays.asList(empty)));
    270         assertTrue(q.addAll(Arrays.asList(ints)));
    271         for (int i = 0; i < SIZE; ++i)
    272             assertEquals(ints[i], q.poll());
    273     }
    274 
    275     /**
    276      * all elements successfully put are contained
    277      */
    278     public void testPut() {
    279         DelayQueue q = new DelayQueue();
    280         for (int i = 0; i < SIZE; ++i) {
    281             PDelay I = new PDelay(i);
    282             q.put(I);
    283             assertTrue(q.contains(I));
    284         }
    285         assertEquals(SIZE, q.size());
    286     }
    287 
    288     /**
    289      * put doesn't block waiting for take
    290      */
    291     public void testPutWithTake() throws InterruptedException {
    292         final DelayQueue q = new DelayQueue();
    293         Thread t = newStartedThread(new CheckedRunnable() {
    294             public void realRun() {
    295                 q.put(new PDelay(0));
    296                 q.put(new PDelay(0));
    297                 q.put(new PDelay(0));
    298                 q.put(new PDelay(0));
    299             }});
    300 
    301         awaitTermination(t);
    302         assertEquals(4, q.size());
    303     }
    304 
    305     /**
    306      * timed offer does not time out
    307      */
    308     public void testTimedOffer() throws InterruptedException {
    309         final DelayQueue q = new DelayQueue();
    310         Thread t = newStartedThread(new CheckedRunnable() {
    311             public void realRun() throws InterruptedException {
    312                 q.put(new PDelay(0));
    313                 q.put(new PDelay(0));
    314                 assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, MILLISECONDS));
    315                 assertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, MILLISECONDS));
    316             }});
    317 
    318         awaitTermination(t);
    319     }
    320 
    321     /**
    322      * take retrieves elements in priority order
    323      */
    324     public void testTake() throws InterruptedException {
    325         DelayQueue q = populatedQueue(SIZE);
    326         for (int i = 0; i < SIZE; ++i) {
    327             assertEquals(new PDelay(i), ((PDelay)q.take()));
    328         }
    329     }
    330 
    331     /**
    332      * Take removes existing elements until empty, then blocks interruptibly
    333      */
    334     public void testBlockingTake() throws InterruptedException {
    335         final DelayQueue q = populatedQueue(SIZE);
    336         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
    337         Thread t = newStartedThread(new CheckedRunnable() {
    338             public void realRun() throws InterruptedException {
    339                 for (int i = 0; i < SIZE; ++i) {
    340                     assertEquals(new PDelay(i), ((PDelay)q.take()));
    341                 }
    342 
    343                 Thread.currentThread().interrupt();
    344                 try {
    345                     q.take();
    346                     shouldThrow();
    347                 } catch (InterruptedException success) {}
    348                 assertFalse(Thread.interrupted());
    349 
    350                 pleaseInterrupt.countDown();
    351                 try {
    352                     q.take();
    353                     shouldThrow();
    354                 } catch (InterruptedException success) {}
    355                 assertFalse(Thread.interrupted());
    356             }});
    357 
    358         await(pleaseInterrupt);
    359         assertThreadStaysAlive(t);
    360         t.interrupt();
    361         awaitTermination(t);
    362     }
    363 
    364     /**
    365      * poll succeeds unless empty
    366      */
    367     public void testPoll() {
    368         DelayQueue q = populatedQueue(SIZE);
    369         for (int i = 0; i < SIZE; ++i) {
    370             assertEquals(new PDelay(i), ((PDelay)q.poll()));
    371         }
    372         assertNull(q.poll());
    373     }
    374 
    375     /**
    376      * timed poll with zero timeout succeeds when non-empty, else times out
    377      */
    378     public void testTimedPoll0() throws InterruptedException {
    379         DelayQueue q = populatedQueue(SIZE);
    380         for (int i = 0; i < SIZE; ++i) {
    381             assertEquals(new PDelay(i), ((PDelay)q.poll(0, MILLISECONDS)));
    382         }
    383         assertNull(q.poll(0, MILLISECONDS));
    384     }
    385 
    386     /**
    387      * timed poll with nonzero timeout succeeds when non-empty, else times out
    388      */
    389     public void testTimedPoll() throws InterruptedException {
    390         DelayQueue q = populatedQueue(SIZE);
    391         for (int i = 0; i < SIZE; ++i) {
    392             long startTime = System.nanoTime();
    393             assertEquals(new PDelay(i), ((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS)));
    394             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
    395         }
    396         long startTime = System.nanoTime();
    397         assertNull(q.poll(timeoutMillis(), MILLISECONDS));
    398         assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    399         checkEmpty(q);
    400     }
    401 
    402     /**
    403      * Interrupted timed poll throws InterruptedException instead of
    404      * returning timeout status
    405      */
    406     public void testInterruptedTimedPoll() throws InterruptedException {
    407         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
    408         Thread t = newStartedThread(new CheckedRunnable() {
    409             public void realRun() throws InterruptedException {
    410                 DelayQueue q = populatedQueue(SIZE);
    411                 for (int i = 0; i < SIZE; ++i) {
    412                     assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS)));
    413                 }
    414 
    415                 Thread.currentThread().interrupt();
    416                 try {
    417                     q.poll(LONG_DELAY_MS, MILLISECONDS);
    418                     shouldThrow();
    419                 } catch (InterruptedException success) {}
    420                 assertFalse(Thread.interrupted());
    421 
    422                 pleaseInterrupt.countDown();
    423                 try {
    424                     q.poll(LONG_DELAY_MS, MILLISECONDS);
    425                     shouldThrow();
    426                 } catch (InterruptedException success) {}
    427                 assertFalse(Thread.interrupted());
    428             }});
    429 
    430         await(pleaseInterrupt);
    431         assertThreadStaysAlive(t);
    432         t.interrupt();
    433         awaitTermination(t);
    434     }
    435 
    436     /**
    437      * peek returns next element, or null if empty
    438      */
    439     public void testPeek() {
    440         DelayQueue q = populatedQueue(SIZE);
    441         for (int i = 0; i < SIZE; ++i) {
    442             assertEquals(new PDelay(i), ((PDelay)q.peek()));
    443             assertEquals(new PDelay(i), ((PDelay)q.poll()));
    444             if (q.isEmpty())
    445                 assertNull(q.peek());
    446             else
    447                 assertFalse(new PDelay(i).equals(q.peek()));
    448         }
    449         assertNull(q.peek());
    450     }
    451 
    452     /**
    453      * element returns next element, or throws NSEE if empty
    454      */
    455     public void testElement() {
    456         DelayQueue q = populatedQueue(SIZE);
    457         for (int i = 0; i < SIZE; ++i) {
    458             assertEquals(new PDelay(i), ((PDelay)q.element()));
    459             q.poll();
    460         }
    461         try {
    462             q.element();
    463             shouldThrow();
    464         } catch (NoSuchElementException success) {}
    465     }
    466 
    467     /**
    468      * remove removes next element, or throws NSEE if empty
    469      */
    470     public void testRemove() {
    471         DelayQueue q = populatedQueue(SIZE);
    472         for (int i = 0; i < SIZE; ++i) {
    473             assertEquals(new PDelay(i), ((PDelay)q.remove()));
    474         }
    475         try {
    476             q.remove();
    477             shouldThrow();
    478         } catch (NoSuchElementException success) {}
    479     }
    480 
    481     /**
    482      * contains(x) reports true when elements added but not yet removed
    483      */
    484     public void testContains() {
    485         DelayQueue q = populatedQueue(SIZE);
    486         for (int i = 0; i < SIZE; ++i) {
    487             assertTrue(q.contains(new PDelay(i)));
    488             q.poll();
    489             assertFalse(q.contains(new PDelay(i)));
    490         }
    491     }
    492 
    493     /**
    494      * clear removes all elements
    495      */
    496     public void testClear() {
    497         DelayQueue q = populatedQueue(SIZE);
    498         q.clear();
    499         assertTrue(q.isEmpty());
    500         assertEquals(0, q.size());
    501         assertEquals(NOCAP, q.remainingCapacity());
    502         PDelay x = new PDelay(1);
    503         q.add(x);
    504         assertFalse(q.isEmpty());
    505         assertTrue(q.contains(x));
    506         q.clear();
    507         assertTrue(q.isEmpty());
    508     }
    509 
    510     /**
    511      * containsAll(c) is true when c contains a subset of elements
    512      */
    513     public void testContainsAll() {
    514         DelayQueue q = populatedQueue(SIZE);
    515         DelayQueue p = new DelayQueue();
    516         for (int i = 0; i < SIZE; ++i) {
    517             assertTrue(q.containsAll(p));
    518             assertFalse(p.containsAll(q));
    519             p.add(new PDelay(i));
    520         }
    521         assertTrue(p.containsAll(q));
    522     }
    523 
    524     /**
    525      * retainAll(c) retains only those elements of c and reports true if changed
    526      */
    527     public void testRetainAll() {
    528         DelayQueue q = populatedQueue(SIZE);
    529         DelayQueue p = populatedQueue(SIZE);
    530         for (int i = 0; i < SIZE; ++i) {
    531             boolean changed = q.retainAll(p);
    532             if (i == 0)
    533                 assertFalse(changed);
    534             else
    535                 assertTrue(changed);
    536 
    537             assertTrue(q.containsAll(p));
    538             assertEquals(SIZE-i, q.size());
    539             p.remove();
    540         }
    541     }
    542 
    543     /**
    544      * removeAll(c) removes only those elements of c and reports true if changed
    545      */
    546     public void testRemoveAll() {
    547         for (int i = 1; i < SIZE; ++i) {
    548             DelayQueue q = populatedQueue(SIZE);
    549             DelayQueue p = populatedQueue(i);
    550             assertTrue(q.removeAll(p));
    551             assertEquals(SIZE-i, q.size());
    552             for (int j = 0; j < i; ++j) {
    553                 PDelay I = (PDelay)(p.remove());
    554                 assertFalse(q.contains(I));
    555             }
    556         }
    557     }
    558 
    559     /**
    560      * toArray contains all elements
    561      */
    562     public void testToArray() throws InterruptedException {
    563         DelayQueue q = populatedQueue(SIZE);
    564         Object[] o = q.toArray();
    565         Arrays.sort(o);
    566         for (int i = 0; i < o.length; i++)
    567             assertSame(o[i], q.take());
    568     }
    569 
    570     /**
    571      * toArray(a) contains all elements
    572      */
    573     public void testToArray2() {
    574         DelayQueue<PDelay> q = populatedQueue(SIZE);
    575         PDelay[] ints = new PDelay[SIZE];
    576         PDelay[] array = q.toArray(ints);
    577         assertSame(ints, array);
    578         Arrays.sort(ints);
    579         for (int i = 0; i < ints.length; i++)
    580             assertSame(ints[i], q.remove());
    581     }
    582 
    583     /**
    584      * toArray(incompatible array type) throws ArrayStoreException
    585      */
    586     public void testToArray1_BadArg() {
    587         DelayQueue q = populatedQueue(SIZE);
    588         try {
    589             q.toArray(new String[10]);
    590             shouldThrow();
    591         } catch (ArrayStoreException success) {}
    592     }
    593 
    594     /**
    595      * iterator iterates through all elements
    596      */
    597     public void testIterator() {
    598         DelayQueue q = populatedQueue(SIZE);
    599         int i = 0;
    600         Iterator it = q.iterator();
    601         while (it.hasNext()) {
    602             assertTrue(q.contains(it.next()));
    603             ++i;
    604         }
    605         assertEquals(i, SIZE);
    606     }
    607 
    608     /**
    609      * iterator.remove removes current element
    610      */
    611     public void testIteratorRemove() {
    612         final DelayQueue q = new DelayQueue();
    613         q.add(new PDelay(2));
    614         q.add(new PDelay(1));
    615         q.add(new PDelay(3));
    616         Iterator it = q.iterator();
    617         it.next();
    618         it.remove();
    619         it = q.iterator();
    620         assertEquals(new PDelay(2), it.next());
    621         assertEquals(new PDelay(3), it.next());
    622         assertFalse(it.hasNext());
    623     }
    624 
    625     /**
    626      * toString contains toStrings of elements
    627      */
    628     public void testToString() {
    629         DelayQueue q = populatedQueue(SIZE);
    630         String s = q.toString();
    631         for (Object e : q)
    632             assertTrue(s.contains(e.toString()));
    633     }
    634 
    635     /**
    636      * timed poll transfers elements across Executor tasks
    637      */
    638     public void testPollInExecutor() {
    639         final DelayQueue q = new DelayQueue();
    640         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
    641         ExecutorService executor = Executors.newFixedThreadPool(2);
    642         executor.execute(new CheckedRunnable() {
    643             public void realRun() throws InterruptedException {
    644                 assertNull(q.poll());
    645                 threadsStarted.await();
    646                 assertNotNull(q.poll(LONG_DELAY_MS, MILLISECONDS));
    647                 checkEmpty(q);
    648             }});
    649 
    650         executor.execute(new CheckedRunnable() {
    651             public void realRun() throws InterruptedException {
    652                 threadsStarted.await();
    653                 q.put(new PDelay(1));
    654             }});
    655 
    656         joinPool(executor);
    657     }
    658 
    659     /**
    660      * Delayed actions do not occur until their delay elapses
    661      */
    662     public void testDelay() throws InterruptedException {
    663         DelayQueue<NanoDelay> q = new DelayQueue<NanoDelay>();
    664         for (int i = 0; i < SIZE; ++i)
    665             q.add(new NanoDelay(1000000L * (SIZE - i)));
    666 
    667         long last = 0;
    668         for (int i = 0; i < SIZE; ++i) {
    669             NanoDelay e = q.take();
    670             long tt = e.getTriggerTime();
    671             assertTrue(System.nanoTime() - tt >= 0);
    672             if (i != 0)
    673                 assertTrue(tt >= last);
    674             last = tt;
    675         }
    676         assertTrue(q.isEmpty());
    677     }
    678 
    679     /**
    680      * peek of a non-empty queue returns non-null even if not expired
    681      */
    682     public void testPeekDelayed() {
    683         DelayQueue q = new DelayQueue();
    684         q.add(new NanoDelay(Long.MAX_VALUE));
    685         assertNotNull(q.peek());
    686     }
    687 
    688     /**
    689      * poll of a non-empty queue returns null if no expired elements.
    690      */
    691     public void testPollDelayed() {
    692         DelayQueue q = new DelayQueue();
    693         q.add(new NanoDelay(Long.MAX_VALUE));
    694         assertNull(q.poll());
    695     }
    696 
    697     /**
    698      * timed poll of a non-empty queue returns null if no expired elements.
    699      */
    700     public void testTimedPollDelayed() throws InterruptedException {
    701         DelayQueue q = new DelayQueue();
    702         q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
    703         assertNull(q.poll(timeoutMillis(), MILLISECONDS));
    704     }
    705 
    706     /**
    707      * drainTo(c) empties queue into another collection c
    708      */
    709     public void testDrainTo() {
    710         DelayQueue q = new DelayQueue();
    711         PDelay[] elems = new PDelay[SIZE];
    712         for (int i = 0; i < SIZE; ++i) {
    713             elems[i] = new PDelay(i);
    714             q.add(elems[i]);
    715         }
    716         ArrayList l = new ArrayList();
    717         q.drainTo(l);
    718         assertEquals(0, q.size());
    719         for (int i = 0; i < SIZE; ++i)
    720             assertEquals(elems[i], l.get(i));
    721         q.add(elems[0]);
    722         q.add(elems[1]);
    723         assertFalse(q.isEmpty());
    724         assertTrue(q.contains(elems[0]));
    725         assertTrue(q.contains(elems[1]));
    726         l.clear();
    727         q.drainTo(l);
    728         assertEquals(0, q.size());
    729         assertEquals(2, l.size());
    730         for (int i = 0; i < 2; ++i)
    731             assertEquals(elems[i], l.get(i));
    732     }
    733 
    734     /**
    735      * drainTo empties queue
    736      */
    737     public void testDrainToWithActivePut() throws InterruptedException {
    738         final DelayQueue q = populatedQueue(SIZE);
    739         Thread t = new Thread(new CheckedRunnable() {
    740             public void realRun() {
    741                 q.put(new PDelay(SIZE+1));
    742             }});
    743 
    744         t.start();
    745         ArrayList l = new ArrayList();
    746         q.drainTo(l);
    747         assertTrue(l.size() >= SIZE);
    748         t.join();
    749         assertTrue(q.size() + l.size() >= SIZE);
    750     }
    751 
    752     /**
    753      * drainTo(c, n) empties first min(n, size) elements of queue into c
    754      */
    755     public void testDrainToN() {
    756         for (int i = 0; i < SIZE + 2; ++i) {
    757             DelayQueue q = populatedQueue(SIZE);
    758             ArrayList l = new ArrayList();
    759             q.drainTo(l, i);
    760             int k = (i < SIZE) ? i : SIZE;
    761             assertEquals(SIZE-k, q.size());
    762             assertEquals(k, l.size());
    763         }
    764     }
    765 
    766 }
    767