ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/LinkedTransferQueueTest.java
Revision: 1.89
Committed: Wed Jan 27 03:38:38 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.88: +2 -2 lines
Log Message:
whitespace

File Contents

# Content
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 John Vint
6 */
7
8 import static java.util.concurrent.TimeUnit.MILLISECONDS;
9
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import java.util.List;
15 import java.util.NoSuchElementException;
16 import java.util.Queue;
17 import java.util.concurrent.BlockingQueue;
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.CountDownLatch;
20 import java.util.concurrent.Executors;
21 import java.util.concurrent.ExecutorService;
22 import java.util.concurrent.LinkedTransferQueue;
23
24 import junit.framework.Test;
25
26 @SuppressWarnings({"unchecked", "rawtypes"})
27 public class LinkedTransferQueueTest extends JSR166TestCase {
28 public static class Generic extends BlockingQueueTest {
29 protected BlockingQueue emptyCollection() {
30 return new LinkedTransferQueue();
31 }
32 }
33
34 public static void main(String[] args) {
35 main(suite(), args);
36 }
37
38 public static Test suite() {
39 class Implementation implements CollectionImplementation {
40 public Class<?> klazz() { return LinkedTransferQueue.class; }
41 public Collection emptyCollection() { return new LinkedTransferQueue(); }
42 public Object makeElement(int i) { return JSR166TestCase.itemFor(i); }
43 public boolean isConcurrent() { return true; }
44 public boolean permitsNulls() { return false; }
45 }
46 return newTestSuite(LinkedTransferQueueTest.class,
47 new Generic().testSuite(),
48 CollectionTest.testSuite(new Implementation()));
49 }
50
51 /**
52 * Constructor builds new queue with size being zero and empty
53 * being true
54 */
55 public void testConstructor1() {
56 mustEqual(0, new LinkedTransferQueue().size());
57 assertTrue(new LinkedTransferQueue().isEmpty());
58 }
59
60 /**
61 * Initializing constructor with null collection throws
62 * NullPointerException
63 */
64 public void testConstructor2() {
65 try {
66 new LinkedTransferQueue(null);
67 shouldThrow();
68 } catch (NullPointerException success) {}
69 }
70
71 /**
72 * Initializing from Collection of null elements throws
73 * NullPointerException
74 */
75 public void testConstructor3() {
76 Collection<Item> elements = Arrays.asList(new Item[SIZE]);
77 try {
78 new LinkedTransferQueue(elements);
79 shouldThrow();
80 } catch (NullPointerException success) {}
81 }
82
83 /**
84 * Initializing constructor with a collection containing some null elements
85 * throws NullPointerException
86 */
87 public void testConstructor4() {
88 Item[] items = new Item[2];
89 items[0] = zero;
90 Collection<Item> elements = Arrays.asList(items);
91 try {
92 new LinkedTransferQueue(elements);
93 shouldThrow();
94 } catch (NullPointerException success) {}
95 }
96
97 /**
98 * Queue contains all elements of the collection it is initialized by
99 */
100 public void testConstructor5() {
101 Item[] items = defaultItems;
102 List<Item> intList = Arrays.asList(items);
103 LinkedTransferQueue<Item> q = new LinkedTransferQueue<>(intList);
104 mustEqual(q.size(), intList.size());
105 mustEqual(q.toString(), intList.toString());
106 assertTrue(Arrays.equals(q.toArray(),
107 intList.toArray()));
108 assertTrue(Arrays.equals(q.toArray(new Object[0]),
109 intList.toArray(new Object[0])));
110 assertTrue(Arrays.equals(q.toArray(new Object[SIZE]),
111 intList.toArray(new Object[SIZE])));
112 for (int i = 0; i < SIZE; ++i) {
113 mustEqual(items[i], q.poll());
114 }
115 }
116
117 /**
118 * remainingCapacity() always returns Integer.MAX_VALUE
119 */
120 public void testRemainingCapacity() {
121 BlockingQueue<Item> q = populatedQueue(SIZE);
122 for (int i = 0; i < SIZE; ++i) {
123 mustEqual(Integer.MAX_VALUE, q.remainingCapacity());
124 mustEqual(SIZE - i, q.size());
125 mustEqual(i, q.remove());
126 }
127 for (int i = 0; i < SIZE; ++i) {
128 mustEqual(Integer.MAX_VALUE, q.remainingCapacity());
129 mustEqual(i, q.size());
130 mustAdd(q, i);
131 }
132 }
133
134 /**
135 * addAll(this) throws IllegalArgumentException
136 */
137 public void testAddAllSelf() {
138 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
139 try {
140 q.addAll(q);
141 shouldThrow();
142 } catch (IllegalArgumentException success) {}
143 }
144
145 /**
146 * addAll of a collection with any null elements throws
147 * NullPointerException after possibly adding some elements
148 */
149 public void testAddAll3() {
150 LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
151 Item[] items = new Item[2]; items[0] = zero;
152 try {
153 q.addAll(Arrays.asList(items));
154 shouldThrow();
155 } catch (NullPointerException success) {}
156 }
157
158 /**
159 * Queue contains all elements, in traversal order, of successful addAll
160 */
161 public void testAddAll5() {
162 Item[] empty = new Item[0];
163 Item[] items = defaultItems;
164 LinkedTransferQueue q = new LinkedTransferQueue();
165 assertFalse(q.addAll(Arrays.asList(empty)));
166 assertTrue(q.addAll(Arrays.asList(items)));
167 for (int i = 0; i < SIZE; ++i) {
168 mustEqual(items[i], q.poll());
169 }
170 }
171
172 /**
173 * all elements successfully put are contained
174 */
175 public void testPut() {
176 LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
177 Item[] items = defaultItems;
178 for (int i = 0; i < SIZE; ++i) {
179 mustEqual(i, q.size());
180 q.put(items[i]);
181 mustContain(q, items[i]);
182 }
183 }
184
185 /**
186 * take retrieves elements in FIFO order
187 */
188 public void testTake() throws InterruptedException {
189 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
190 for (int i = 0; i < SIZE; ++i) {
191 mustEqual(i, q.take());
192 }
193 }
194
195 /**
196 * take removes existing elements until empty, then blocks interruptibly
197 */
198 public void testBlockingTake() throws InterruptedException {
199 final BlockingQueue<Item> q = populatedQueue(SIZE);
200 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
201 Thread t = newStartedThread(new CheckedRunnable() {
202 public void realRun() throws InterruptedException {
203 for (int i = 0; i < SIZE; i++) mustEqual(i, q.take());
204
205 Thread.currentThread().interrupt();
206 try {
207 q.take();
208 shouldThrow();
209 } catch (InterruptedException success) {}
210 assertFalse(Thread.interrupted());
211
212 pleaseInterrupt.countDown();
213 try {
214 q.take();
215 shouldThrow();
216 } catch (InterruptedException success) {}
217 assertFalse(Thread.interrupted());
218 }});
219
220 await(pleaseInterrupt);
221 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING);
222 t.interrupt();
223 awaitTermination(t);
224 }
225
226 /**
227 * poll succeeds unless empty
228 */
229 public void testPoll() throws InterruptedException {
230 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
231 for (int i = 0; i < SIZE; ++i) {
232 mustEqual(i, q.poll());
233 }
234 assertNull(q.poll());
235 checkEmpty(q);
236 }
237
238 /**
239 * timed poll with zero timeout succeeds when non-empty, else times out
240 */
241 public void testTimedPoll0() throws InterruptedException {
242 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
243 for (int i = 0; i < SIZE; ++i) {
244 mustEqual(i, q.poll(0, MILLISECONDS));
245 }
246 assertNull(q.poll(0, MILLISECONDS));
247 checkEmpty(q);
248 }
249
250 /**
251 * timed poll with nonzero timeout succeeds when non-empty, else times out
252 */
253 public void testTimedPoll() throws InterruptedException {
254 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
255 long startTime = System.nanoTime();
256 for (int i = 0; i < SIZE; ++i)
257 mustEqual(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
258 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
259
260 startTime = System.nanoTime();
261 assertNull(q.poll(timeoutMillis(), MILLISECONDS));
262 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
263 checkEmpty(q);
264 }
265
266 /**
267 * Interrupted timed poll throws InterruptedException instead of
268 * returning timeout status
269 */
270 public void testInterruptedTimedPoll() throws InterruptedException {
271 final BlockingQueue<Item> q = populatedQueue(SIZE);
272 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
273 Thread t = newStartedThread(new CheckedRunnable() {
274 public void realRun() throws InterruptedException {
275 for (int i = 0; i < SIZE; i++)
276 mustEqual(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
277
278 Thread.currentThread().interrupt();
279 try {
280 q.poll(randomTimeout(), randomTimeUnit());
281 shouldThrow();
282 } catch (InterruptedException success) {}
283 assertFalse(Thread.interrupted());
284
285 pleaseInterrupt.countDown();
286 try {
287 q.poll(LONGER_DELAY_MS, MILLISECONDS);
288 shouldThrow();
289 } catch (InterruptedException success) {}
290 assertFalse(Thread.interrupted());
291 }});
292
293 await(pleaseInterrupt);
294 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
295 t.interrupt();
296 awaitTermination(t);
297 checkEmpty(q);
298 }
299
300 /**
301 * timed poll after thread interrupted throws InterruptedException
302 * instead of returning timeout status
303 */
304 public void testTimedPollAfterInterrupt() throws InterruptedException {
305 final BlockingQueue<Item> q = populatedQueue(SIZE);
306 Thread t = newStartedThread(new CheckedRunnable() {
307 public void realRun() throws InterruptedException {
308 Thread.currentThread().interrupt();
309 for (int i = 0; i < SIZE; ++i)
310 mustEqual(i, q.poll(randomTimeout(), randomTimeUnit()));
311 try {
312 q.poll(randomTimeout(), randomTimeUnit());
313 shouldThrow();
314 } catch (InterruptedException success) {}
315 assertFalse(Thread.interrupted());
316 }});
317
318 awaitTermination(t);
319 checkEmpty(q);
320 }
321
322 /**
323 * peek returns next element, or null if empty
324 */
325 public void testPeek() throws InterruptedException {
326 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
327 for (int i = 0; i < SIZE; ++i) {
328 mustEqual(i, q.peek());
329 mustEqual(i, q.poll());
330 assertTrue(q.peek() == null ||
331 i != q.peek().value);
332 }
333 assertNull(q.peek());
334 checkEmpty(q);
335 }
336
337 /**
338 * element returns next element, or throws NoSuchElementException if empty
339 */
340 public void testElement() throws InterruptedException {
341 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
342 for (int i = 0; i < SIZE; ++i) {
343 mustEqual(i, q.element());
344 mustEqual(i, q.poll());
345 }
346 try {
347 q.element();
348 shouldThrow();
349 } catch (NoSuchElementException success) {}
350 checkEmpty(q);
351 }
352
353 /**
354 * remove removes next element, or throws NoSuchElementException if empty
355 */
356 public void testRemove() throws InterruptedException {
357 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
358 for (int i = 0; i < SIZE; ++i) {
359 mustEqual(i, q.remove());
360 }
361 try {
362 q.remove();
363 shouldThrow();
364 } catch (NoSuchElementException success) {}
365 checkEmpty(q);
366 }
367
368 /**
369 * An add following remove(x) succeeds
370 */
371 public void testRemoveElementAndAdd() throws InterruptedException {
372 LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
373 mustAdd(q, one);
374 mustAdd(q, two);
375 mustRemove(q, one);
376 mustRemove(q, two);
377 mustAdd(q, three);
378 mustEqual(q.take(), three);
379 }
380
381 /**
382 * contains(x) reports true when elements added but not yet removed
383 */
384 public void testContains() {
385 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
386 for (int i = 0; i < SIZE; ++i) {
387 mustContain(q, i);
388 mustEqual(i, q.poll());
389 mustNotContain(q, i);
390 }
391 }
392
393 /**
394 * clear removes all elements
395 */
396 public void testClear() throws InterruptedException {
397 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
398 q.clear();
399 checkEmpty(q);
400 mustEqual(Integer.MAX_VALUE, q.remainingCapacity());
401 q.add(one);
402 assertFalse(q.isEmpty());
403 mustEqual(1, q.size());
404 mustContain(q, one);
405 q.clear();
406 checkEmpty(q);
407 }
408
409 /**
410 * containsAll(c) is true when c contains a subset of elements
411 */
412 public void testContainsAll() {
413 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
414 LinkedTransferQueue<Item> p = new LinkedTransferQueue<>();
415 for (int i = 0; i < SIZE; ++i) {
416 assertTrue(q.containsAll(p));
417 assertFalse(p.containsAll(q));
418 mustAdd(p, i);
419 }
420 assertTrue(p.containsAll(q));
421 }
422
423 /**
424 * retainAll(c) retains only those elements of c and reports true
425 * if changed
426 */
427 public void testRetainAll() {
428 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
429 LinkedTransferQueue<Item> p = populatedQueue(SIZE);
430 for (int i = 0; i < SIZE; ++i) {
431 boolean changed = q.retainAll(p);
432 if (i == 0) {
433 assertFalse(changed);
434 } else {
435 assertTrue(changed);
436 }
437 assertTrue(q.containsAll(p));
438 mustEqual(SIZE - i, q.size());
439 p.remove();
440 }
441 }
442
443 /**
444 * removeAll(c) removes only those elements of c and reports true
445 * if changed
446 */
447 public void testRemoveAll() {
448 for (int i = 1; i < SIZE; ++i) {
449 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
450 LinkedTransferQueue<Item> p = populatedQueue(i);
451 assertTrue(q.removeAll(p));
452 mustEqual(SIZE - i, q.size());
453 for (int j = 0; j < i; ++j) {
454 mustNotContain(q, p.remove());
455 }
456 }
457 }
458
459 /**
460 * toArray() contains all elements in FIFO order
461 */
462 public void testToArray() {
463 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
464 Object[] a = q.toArray();
465 assertSame(Object[].class, a.getClass());
466 for (Object o : a)
467 assertSame(o, q.poll());
468 assertTrue(q.isEmpty());
469 }
470
471 /**
472 * toArray(a) contains all elements in FIFO order
473 */
474 public void testToArray2() {
475 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
476 Item[] items = new Item[SIZE];
477 Item[] array = q.toArray(items);
478 assertSame(items, array);
479 for (Item o : items)
480 assertSame(o, q.poll());
481 assertTrue(q.isEmpty());
482 }
483
484 /**
485 * toArray(incompatible array type) throws ArrayStoreException
486 */
487 @SuppressWarnings("CollectionToArraySafeParameter")
488 public void testToArray_incompatibleArrayType() {
489 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
490 try {
491 q.toArray(new String[10]);
492 shouldThrow();
493 } catch (ArrayStoreException success) {}
494 }
495
496 /**
497 * iterator iterates through all elements
498 */
499 public void testIterator() throws InterruptedException {
500 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
501 Iterator<? extends Item> it = q.iterator();
502 int i;
503 for (i = 0; it.hasNext(); i++)
504 mustContain(q, it.next());
505 mustEqual(i, SIZE);
506 assertIteratorExhausted(it);
507
508 it = q.iterator();
509 for (i = 0; it.hasNext(); i++)
510 mustEqual(it.next(), q.take());
511 mustEqual(i, SIZE);
512 assertIteratorExhausted(it);
513 }
514
515 /**
516 * iterator of empty collection has no elements
517 */
518 public void testEmptyIterator() {
519 assertIteratorExhausted(new LinkedTransferQueue().iterator());
520 }
521
522 /**
523 * iterator.remove() removes current element
524 */
525 public void testIteratorRemove() {
526 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
527 q.add(two);
528 q.add(one);
529 q.add(three);
530
531 Iterator<? extends Item> it = q.iterator();
532 it.next();
533 it.remove();
534
535 it = q.iterator();
536 assertSame(it.next(), one);
537 assertSame(it.next(), three);
538 assertFalse(it.hasNext());
539 }
540
541 /**
542 * iterator ordering is FIFO
543 */
544 public void testIteratorOrdering() {
545 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
546 mustEqual(Integer.MAX_VALUE, q.remainingCapacity());
547 q.add(one);
548 q.add(two);
549 q.add(three);
550 mustEqual(Integer.MAX_VALUE, q.remainingCapacity());
551 int k = 0;
552 for (Item n : q) {
553 mustEqual(++k, n);
554 }
555 mustEqual(3, k);
556 }
557
558 /**
559 * Modifications do not cause iterators to fail
560 */
561 public void testWeaklyConsistentIteration() {
562 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
563 q.add(one);
564 q.add(two);
565 q.add(three);
566 for (Iterator<? extends Item> it = q.iterator(); it.hasNext();) {
567 q.remove();
568 it.next();
569 }
570 mustEqual(0, q.size());
571 }
572
573 /**
574 * toString contains toStrings of elements
575 */
576 public void testToString() {
577 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
578 String s = q.toString();
579 for (int i = 0; i < SIZE; ++i) {
580 assertTrue(s.contains(String.valueOf(i)));
581 }
582 }
583
584 /**
585 * offer transfers elements across Executor tasks
586 */
587 public void testOfferInExecutor() {
588 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
589 final CheckedBarrier threadsStarted = new CheckedBarrier(2);
590 final ExecutorService executor = Executors.newFixedThreadPool(2);
591 try (PoolCleaner cleaner = cleaner(executor)) {
592
593 executor.execute(new CheckedRunnable() {
594 public void realRun() throws InterruptedException {
595 threadsStarted.await();
596 long startTime = System.nanoTime();
597 assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
598 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
599 }});
600
601 executor.execute(new CheckedRunnable() {
602 public void realRun() throws InterruptedException {
603 threadsStarted.await();
604 assertSame(one, q.take());
605 checkEmpty(q);
606 }});
607 }
608 }
609
610 /**
611 * timed poll retrieves elements across Executor threads
612 */
613 public void testPollInExecutor() {
614 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
615 final CheckedBarrier threadsStarted = new CheckedBarrier(2);
616 final ExecutorService executor = Executors.newFixedThreadPool(2);
617 try (PoolCleaner cleaner = cleaner(executor)) {
618
619 executor.execute(new CheckedRunnable() {
620 public void realRun() throws InterruptedException {
621 assertNull(q.poll());
622 threadsStarted.await();
623 long startTime = System.nanoTime();
624 assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
625 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
626 checkEmpty(q);
627 }});
628
629 executor.execute(new CheckedRunnable() {
630 public void realRun() throws InterruptedException {
631 threadsStarted.await();
632 q.put(one);
633 }});
634 }
635 }
636
637 /**
638 * A deserialized/reserialized queue has same elements in same order
639 */
640 public void testSerialization() throws Exception {
641 Queue<Item> x = populatedQueue(SIZE);
642 Queue<Item> y = serialClone(x);
643
644 assertNotSame(y, x);
645 mustEqual(x.size(), y.size());
646 mustEqual(x.toString(), y.toString());
647 assertTrue(Arrays.equals(x.toArray(), y.toArray()));
648 while (!x.isEmpty()) {
649 assertFalse(y.isEmpty());
650 mustEqual(x.remove(), y.remove());
651 }
652 assertTrue(y.isEmpty());
653 }
654
655 /**
656 * drainTo(c) empties queue into another collection c
657 */
658 public void testDrainTo() {
659 LinkedTransferQueue<Item> q = populatedQueue(SIZE);
660 ArrayList l = new ArrayList();
661 q.drainTo(l);
662 mustEqual(0, q.size());
663 mustEqual(SIZE, l.size());
664 for (int i = 0; i < SIZE; ++i) {
665 mustEqual(i, l.get(i));
666 }
667 q.add(zero);
668 q.add(one);
669 assertFalse(q.isEmpty());
670 mustContain(q, zero);
671 mustContain(q, one);
672 l.clear();
673 q.drainTo(l);
674 mustEqual(0, q.size());
675 mustEqual(2, l.size());
676 for (int i = 0; i < 2; ++i) {
677 mustEqual(i, l.get(i));
678 }
679 }
680
681 /**
682 * drainTo(c) empties full queue, unblocking a waiting put.
683 */
684 public void testDrainToWithActivePut() throws InterruptedException {
685 final LinkedTransferQueue<Item> q = populatedQueue(SIZE);
686 Thread t = newStartedThread(new CheckedRunnable() {
687 public void realRun() {
688 q.put(new Item(SIZE + 1));
689 }});
690 ArrayList l = new ArrayList();
691 q.drainTo(l);
692 assertTrue(l.size() >= SIZE);
693 for (int i = 0; i < SIZE; ++i)
694 mustEqual(i, l.get(i));
695 awaitTermination(t);
696 assertTrue(q.size() + l.size() >= SIZE);
697 }
698
699 /**
700 * drainTo(c, n) empties first min(n, size) elements of queue into c
701 */
702 public void testDrainToN() {
703 LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
704 for (int i = 0; i < SIZE + 2; ++i) {
705 for (int j = 0; j < SIZE; j++) {
706 mustOffer(q, j);
707 }
708 ArrayList l = new ArrayList();
709 q.drainTo(l, i);
710 int k = (i < SIZE) ? i : SIZE;
711 mustEqual(k, l.size());
712 mustEqual(SIZE - k, q.size());
713 for (int j = 0; j < k; ++j)
714 mustEqual(j, l.get(j));
715 do {} while (q.poll() != null);
716 }
717 }
718
719 /**
720 * timed poll() or take() increments the waiting consumer count;
721 * offer(e) decrements the waiting consumer count
722 */
723 public void testWaitingConsumer() throws InterruptedException {
724 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
725 mustEqual(0, q.getWaitingConsumerCount());
726 assertFalse(q.hasWaitingConsumer());
727 final CountDownLatch threadStarted = new CountDownLatch(1);
728
729 Thread t = newStartedThread(new CheckedRunnable() {
730 public void realRun() throws InterruptedException {
731 threadStarted.countDown();
732 long startTime = System.nanoTime();
733 assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
734 mustEqual(0, q.getWaitingConsumerCount());
735 assertFalse(q.hasWaitingConsumer());
736 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
737 }});
738
739 threadStarted.await();
740 Callable<Boolean> oneConsumer = new Callable<>() {
741 public Boolean call() {
742 return q.hasWaitingConsumer()
743 && q.getWaitingConsumerCount() == 1; }};
744 waitForThreadToEnterWaitState(t, oneConsumer);
745
746 assertTrue(q.offer(one));
747 mustEqual(0, q.getWaitingConsumerCount());
748 assertFalse(q.hasWaitingConsumer());
749
750 awaitTermination(t);
751 }
752
753 /**
754 * transfer(null) throws NullPointerException
755 */
756 public void testTransfer1() throws InterruptedException {
757 try {
758 LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
759 q.transfer(null);
760 shouldThrow();
761 } catch (NullPointerException success) {}
762 }
763
764 /**
765 * transfer waits until a poll occurs. The transferred element
766 * is returned by the associated poll.
767 */
768 public void testTransfer2() throws InterruptedException {
769 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
770 final CountDownLatch threadStarted = new CountDownLatch(1);
771
772 Thread t = newStartedThread(new CheckedRunnable() {
773 public void realRun() throws InterruptedException {
774 threadStarted.countDown();
775 q.transfer(five);
776 checkEmpty(q);
777 }});
778
779 threadStarted.await();
780 Callable<Boolean> oneElement = new Callable<>() {
781 public Boolean call() {
782 return !q.isEmpty() && q.size() == 1; }};
783 waitForThreadToEnterWaitState(t, oneElement);
784
785 assertSame(five, q.poll());
786 checkEmpty(q);
787 awaitTermination(t);
788 }
789
790 /**
791 * transfer waits until a poll occurs, and then transfers in fifo order
792 */
793 public void testTransfer3() throws InterruptedException {
794 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
795
796 Thread first = newStartedThread(new CheckedRunnable() {
797 public void realRun() throws InterruptedException {
798 q.transfer(four);
799 mustNotContain(q, four);
800 mustEqual(1, q.size());
801 }});
802
803 Thread interruptedThread = newStartedThread(
804 new CheckedInterruptedRunnable() {
805 public void realRun() throws InterruptedException {
806 while (q.isEmpty())
807 Thread.yield();
808 q.transfer(five);
809 }});
810
811 while (q.size() < 2)
812 Thread.yield();
813 mustEqual(2, q.size());
814 assertSame(four, q.poll());
815 first.join();
816 mustEqual(1, q.size());
817 interruptedThread.interrupt();
818 interruptedThread.join();
819 checkEmpty(q);
820 }
821
822 /**
823 * transfer waits until a poll occurs, at which point the polling
824 * thread returns the element
825 */
826 public void testTransfer4() throws InterruptedException {
827 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
828
829 Thread t = newStartedThread(new CheckedRunnable() {
830 public void realRun() throws InterruptedException {
831 q.transfer(four);
832 mustNotContain(q, four);
833 assertSame(three, q.poll());
834 }});
835
836 while (q.isEmpty())
837 Thread.yield();
838 assertFalse(q.isEmpty());
839 mustEqual(1, q.size());
840 assertTrue(q.offer(three));
841 assertSame(four, q.poll());
842 awaitTermination(t);
843 }
844
845 /**
846 * transfer waits until a take occurs. The transferred element
847 * is returned by the associated take.
848 */
849 public void testTransfer5() throws InterruptedException {
850 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
851
852 Thread t = newStartedThread(new CheckedRunnable() {
853 public void realRun() throws InterruptedException {
854 q.transfer(four);
855 checkEmpty(q);
856 }});
857
858 while (q.isEmpty())
859 Thread.yield();
860 assertFalse(q.isEmpty());
861 mustEqual(1, q.size());
862 assertSame(four, q.take());
863 checkEmpty(q);
864 awaitTermination(t);
865 }
866
867 /**
868 * tryTransfer(null) throws NullPointerException
869 */
870 public void testTryTransfer1() {
871 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
872 try {
873 q.tryTransfer(null);
874 shouldThrow();
875 } catch (NullPointerException success) {}
876 }
877
878 /**
879 * tryTransfer returns false and does not enqueue if there are no
880 * consumers waiting to poll or take.
881 */
882 public void testTryTransfer2() throws InterruptedException {
883 final LinkedTransferQueue<Object> q = new LinkedTransferQueue<>();
884 assertFalse(q.tryTransfer(new Object()));
885 assertFalse(q.hasWaitingConsumer());
886 checkEmpty(q);
887 }
888
889 /**
890 * If there is a consumer waiting in timed poll, tryTransfer
891 * returns true while successfully transfering object.
892 */
893 public void testTryTransfer3() throws InterruptedException {
894 final Object hotPotato = new Object();
895 final LinkedTransferQueue<Object> q = new LinkedTransferQueue<>();
896
897 Thread t = newStartedThread(new CheckedRunnable() {
898 public void realRun() {
899 while (! q.hasWaitingConsumer())
900 Thread.yield();
901 assertTrue(q.hasWaitingConsumer());
902 checkEmpty(q);
903 assertTrue(q.tryTransfer(hotPotato));
904 }});
905
906 long startTime = System.nanoTime();
907 assertSame(hotPotato, q.poll(LONG_DELAY_MS, MILLISECONDS));
908 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
909 checkEmpty(q);
910 awaitTermination(t);
911 }
912
913 /**
914 * If there is a consumer waiting in take, tryTransfer returns
915 * true while successfully transfering object.
916 */
917 public void testTryTransfer4() throws InterruptedException {
918 final Object hotPotato = new Object();
919 final LinkedTransferQueue<Object> q = new LinkedTransferQueue<>();
920
921 Thread t = newStartedThread(new CheckedRunnable() {
922 public void realRun() {
923 while (! q.hasWaitingConsumer())
924 Thread.yield();
925 assertTrue(q.hasWaitingConsumer());
926 checkEmpty(q);
927 assertTrue(q.tryTransfer(hotPotato));
928 }});
929
930 assertSame(q.take(), hotPotato);
931 checkEmpty(q);
932 awaitTermination(t);
933 }
934
935 /**
936 * tryTransfer blocks interruptibly if no takers
937 */
938 public void testTryTransfer5() throws InterruptedException {
939 final LinkedTransferQueue<Object> q = new LinkedTransferQueue<>();
940 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
941 assertTrue(q.isEmpty());
942
943 Thread t = newStartedThread(new CheckedRunnable() {
944 public void realRun() throws InterruptedException {
945 Thread.currentThread().interrupt();
946 try {
947 q.tryTransfer(new Object(), randomTimeout(), randomTimeUnit());
948 shouldThrow();
949 } catch (InterruptedException success) {}
950 assertFalse(Thread.interrupted());
951
952 pleaseInterrupt.countDown();
953 try {
954 q.tryTransfer(new Object(), LONGER_DELAY_MS, MILLISECONDS);
955 shouldThrow();
956 } catch (InterruptedException success) {}
957 assertFalse(Thread.interrupted());
958 }});
959
960 await(pleaseInterrupt);
961 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
962 t.interrupt();
963 awaitTermination(t);
964 checkEmpty(q);
965 }
966
967 /**
968 * tryTransfer gives up after the timeout and returns false
969 */
970 public void testTryTransfer6() throws InterruptedException {
971 final LinkedTransferQueue<Object> q = new LinkedTransferQueue<>();
972
973 Thread t = newStartedThread(new CheckedRunnable() {
974 public void realRun() throws InterruptedException {
975 long startTime = System.nanoTime();
976 assertFalse(q.tryTransfer(new Object(),
977 timeoutMillis(), MILLISECONDS));
978 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
979 checkEmpty(q);
980 }});
981
982 awaitTermination(t);
983 checkEmpty(q);
984 }
985
986 /**
987 * tryTransfer waits for any elements previously in to be removed
988 * before transfering to a poll or take
989 */
990 public void testTryTransfer7() throws InterruptedException {
991 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
992 assertTrue(q.offer(four));
993
994 Thread t = newStartedThread(new CheckedRunnable() {
995 public void realRun() throws InterruptedException {
996 long startTime = System.nanoTime();
997 assertTrue(q.tryTransfer(five, LONG_DELAY_MS, MILLISECONDS));
998 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
999 checkEmpty(q);
1000 }});
1001
1002 while (q.size() != 2)
1003 Thread.yield();
1004 mustEqual(2, q.size());
1005 assertSame(four, q.poll());
1006 assertSame(five, q.poll());
1007 checkEmpty(q);
1008 awaitTermination(t);
1009 }
1010
1011 /**
1012 * tryTransfer attempts to enqueue into the queue and fails
1013 * returning false not enqueueing and the successive poll is null
1014 */
1015 public void testTryTransfer8() throws InterruptedException {
1016 final LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
1017 assertTrue(q.offer(four));
1018 mustEqual(1, q.size());
1019 long startTime = System.nanoTime();
1020 assertFalse(q.tryTransfer(five, timeoutMillis(), MILLISECONDS));
1021 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
1022 mustEqual(1, q.size());
1023 assertSame(four, q.poll());
1024 assertNull(q.poll());
1025 checkEmpty(q);
1026 }
1027
1028 private LinkedTransferQueue<Item> populatedQueue(int n) {
1029 LinkedTransferQueue<Item> q = new LinkedTransferQueue<>();
1030 checkEmpty(q);
1031 for (int i = 0; i < n; i++) {
1032 mustEqual(i, q.size());
1033 mustOffer(q, i);
1034 mustEqual(Integer.MAX_VALUE, q.remainingCapacity());
1035 }
1036 assertFalse(q.isEmpty());
1037 return q;
1038 }
1039
1040 /**
1041 * remove(null), contains(null) always return false
1042 */
1043 public void testNeverContainsNull() {
1044 Collection<?>[] qs = {
1045 new LinkedTransferQueue<>(),
1046 populatedQueue(2),
1047 };
1048
1049 for (Collection<?> q : qs) {
1050 assertFalse(q.contains(null));
1051 assertFalse(q.remove(null));
1052 }
1053 }
1054 }