ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentLinkedDequeTest.java
Revision: 1.35
Committed: Wed Aug 14 23:06:11 2019 UTC (4 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.34: +0 -4 lines
Log Message:
fix very rare race in testInterruptedFailingAcquire

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 Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9 import java.util.Arrays;
10 import java.util.Collection;
11 import java.util.Deque;
12 import java.util.Iterator;
13 import java.util.NoSuchElementException;
14 import java.util.Queue;
15 import java.util.Random;
16 import java.util.concurrent.CompletableFuture;
17 import java.util.concurrent.ConcurrentLinkedDeque;
18 import java.util.concurrent.ThreadLocalRandom;
19 import java.util.concurrent.atomic.LongAdder;
20
21 import junit.framework.Test;
22
23 public class ConcurrentLinkedDequeTest extends JSR166TestCase {
24
25 public static void main(String[] args) {
26 main(suite(), args);
27 }
28
29 public static Test suite() {
30 class Implementation implements CollectionImplementation {
31 public Class<?> klazz() { return ConcurrentLinkedDeque.class; }
32 public Collection emptyCollection() { return new ConcurrentLinkedDeque(); }
33 public Object makeElement(int i) { return i; }
34 public boolean isConcurrent() { return true; }
35 public boolean permitsNulls() { return false; }
36 }
37 return newTestSuite(ConcurrentLinkedDequeTest.class,
38 CollectionTest.testSuite(new Implementation()));
39 }
40
41 /**
42 * Returns a new deque of given size containing consecutive
43 * Integers 0 ... n - 1.
44 */
45 private static ConcurrentLinkedDeque<Integer> populatedDeque(int n) {
46 ConcurrentLinkedDeque<Integer> q = new ConcurrentLinkedDeque<>();
47 assertTrue(q.isEmpty());
48 for (int i = 0; i < n; ++i)
49 assertTrue(q.offer(new Integer(i)));
50 assertFalse(q.isEmpty());
51 assertEquals(n, q.size());
52 assertEquals((Integer) 0, q.peekFirst());
53 assertEquals((Integer) (n - 1), q.peekLast());
54 return q;
55 }
56
57 /**
58 * new deque is empty
59 */
60 public void testConstructor1() {
61 assertTrue(new ConcurrentLinkedDeque().isEmpty());
62 assertEquals(0, new ConcurrentLinkedDeque().size());
63 }
64
65 /**
66 * Initializing from null Collection throws NPE
67 */
68 public void testConstructor3() {
69 try {
70 new ConcurrentLinkedDeque((Collection)null);
71 shouldThrow();
72 } catch (NullPointerException success) {}
73 }
74
75 /**
76 * Initializing from Collection of null elements throws NPE
77 */
78 public void testConstructor4() {
79 try {
80 new ConcurrentLinkedDeque(Arrays.asList(new Integer[SIZE]));
81 shouldThrow();
82 } catch (NullPointerException success) {}
83 }
84
85 /**
86 * Initializing from Collection with some null elements throws NPE
87 */
88 public void testConstructor5() {
89 Integer[] ints = new Integer[SIZE];
90 for (int i = 0; i < SIZE - 1; ++i)
91 ints[i] = new Integer(i);
92 try {
93 new ConcurrentLinkedDeque(Arrays.asList(ints));
94 shouldThrow();
95 } catch (NullPointerException success) {}
96 }
97
98 /**
99 * Deque contains all elements of collection used to initialize
100 */
101 public void testConstructor6() {
102 Integer[] ints = new Integer[SIZE];
103 for (int i = 0; i < SIZE; ++i)
104 ints[i] = new Integer(i);
105 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(Arrays.asList(ints));
106 for (int i = 0; i < SIZE; ++i)
107 assertEquals(ints[i], q.poll());
108 }
109
110 /**
111 * isEmpty is true before add, false after
112 */
113 public void testEmpty() {
114 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
115 assertTrue(q.isEmpty());
116 q.add(one);
117 assertFalse(q.isEmpty());
118 q.add(two);
119 q.remove();
120 q.remove();
121 assertTrue(q.isEmpty());
122 }
123
124 /**
125 * size() changes when elements added and removed
126 */
127 public void testSize() {
128 ConcurrentLinkedDeque q = populatedDeque(SIZE);
129 for (int i = 0; i < SIZE; ++i) {
130 assertEquals(SIZE - i, q.size());
131 q.remove();
132 }
133 for (int i = 0; i < SIZE; ++i) {
134 assertEquals(i, q.size());
135 q.add(new Integer(i));
136 }
137 }
138
139 /**
140 * push(null) throws NPE
141 */
142 public void testPushNull() {
143 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
144 try {
145 q.push(null);
146 shouldThrow();
147 } catch (NullPointerException success) {}
148 }
149
150 /**
151 * peekFirst() returns element inserted with push
152 */
153 public void testPush() {
154 ConcurrentLinkedDeque q = populatedDeque(3);
155 q.pollLast();
156 q.push(four);
157 assertSame(four, q.peekFirst());
158 }
159
160 /**
161 * pop() removes first element, or throws NSEE if empty
162 */
163 public void testPop() {
164 ConcurrentLinkedDeque q = populatedDeque(SIZE);
165 for (int i = 0; i < SIZE; ++i) {
166 assertEquals(i, q.pop());
167 }
168 try {
169 q.pop();
170 shouldThrow();
171 } catch (NoSuchElementException success) {}
172 }
173
174 /**
175 * offer(null) throws NPE
176 */
177 public void testOfferNull() {
178 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
179 try {
180 q.offer(null);
181 shouldThrow();
182 } catch (NullPointerException success) {}
183 }
184
185 /**
186 * offerFirst(null) throws NPE
187 */
188 public void testOfferFirstNull() {
189 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
190 try {
191 q.offerFirst(null);
192 shouldThrow();
193 } catch (NullPointerException success) {}
194 }
195
196 /**
197 * offerLast(null) throws NPE
198 */
199 public void testOfferLastNull() {
200 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
201 try {
202 q.offerLast(null);
203 shouldThrow();
204 } catch (NullPointerException success) {}
205 }
206
207 /**
208 * offer(x) succeeds
209 */
210 public void testOffer() {
211 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
212 assertTrue(q.offer(zero));
213 assertTrue(q.offer(one));
214 assertSame(zero, q.peekFirst());
215 assertSame(one, q.peekLast());
216 }
217
218 /**
219 * offerFirst(x) succeeds
220 */
221 public void testOfferFirst() {
222 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
223 assertTrue(q.offerFirst(zero));
224 assertTrue(q.offerFirst(one));
225 assertSame(one, q.peekFirst());
226 assertSame(zero, q.peekLast());
227 }
228
229 /**
230 * offerLast(x) succeeds
231 */
232 public void testOfferLast() {
233 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
234 assertTrue(q.offerLast(zero));
235 assertTrue(q.offerLast(one));
236 assertSame(zero, q.peekFirst());
237 assertSame(one, q.peekLast());
238 }
239
240 /**
241 * add(null) throws NPE
242 */
243 public void testAddNull() {
244 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
245 try {
246 q.add(null);
247 shouldThrow();
248 } catch (NullPointerException success) {}
249 }
250
251 /**
252 * addFirst(null) throws NPE
253 */
254 public void testAddFirstNull() {
255 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
256 try {
257 q.addFirst(null);
258 shouldThrow();
259 } catch (NullPointerException success) {}
260 }
261
262 /**
263 * addLast(null) throws NPE
264 */
265 public void testAddLastNull() {
266 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
267 try {
268 q.addLast(null);
269 shouldThrow();
270 } catch (NullPointerException success) {}
271 }
272
273 /**
274 * add(x) succeeds
275 */
276 public void testAdd() {
277 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
278 assertTrue(q.add(zero));
279 assertTrue(q.add(one));
280 assertSame(zero, q.peekFirst());
281 assertSame(one, q.peekLast());
282 }
283
284 /**
285 * addFirst(x) succeeds
286 */
287 public void testAddFirst() {
288 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
289 q.addFirst(zero);
290 q.addFirst(one);
291 assertSame(one, q.peekFirst());
292 assertSame(zero, q.peekLast());
293 }
294
295 /**
296 * addLast(x) succeeds
297 */
298 public void testAddLast() {
299 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
300 q.addLast(zero);
301 q.addLast(one);
302 assertSame(zero, q.peekFirst());
303 assertSame(one, q.peekLast());
304 }
305
306 /**
307 * addAll(null) throws NPE
308 */
309 public void testAddAll1() {
310 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
311 try {
312 q.addAll(null);
313 shouldThrow();
314 } catch (NullPointerException success) {}
315 }
316
317 /**
318 * addAll(this) throws IllegalArgumentException
319 */
320 public void testAddAllSelf() {
321 ConcurrentLinkedDeque q = populatedDeque(SIZE);
322 try {
323 q.addAll(q);
324 shouldThrow();
325 } catch (IllegalArgumentException success) {}
326 }
327
328 /**
329 * addAll of a collection with null elements throws NPE
330 */
331 public void testAddAll2() {
332 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
333 try {
334 q.addAll(Arrays.asList(new Integer[SIZE]));
335 shouldThrow();
336 } catch (NullPointerException success) {}
337 }
338
339 /**
340 * addAll of a collection with any null elements throws NPE after
341 * possibly adding some elements
342 */
343 public void testAddAll3() {
344 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
345 Integer[] ints = new Integer[SIZE];
346 for (int i = 0; i < SIZE - 1; ++i)
347 ints[i] = new Integer(i);
348 try {
349 q.addAll(Arrays.asList(ints));
350 shouldThrow();
351 } catch (NullPointerException success) {}
352 }
353
354 /**
355 * Deque contains all elements, in traversal order, of successful addAll
356 */
357 public void testAddAll5() {
358 Integer[] empty = new Integer[0];
359 Integer[] ints = new Integer[SIZE];
360 for (int i = 0; i < SIZE; ++i)
361 ints[i] = new Integer(i);
362 ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
363 assertFalse(q.addAll(Arrays.asList(empty)));
364 assertTrue(q.addAll(Arrays.asList(ints)));
365 for (int i = 0; i < SIZE; ++i)
366 assertEquals(ints[i], q.poll());
367 }
368
369 /**
370 * pollFirst() succeeds unless empty
371 */
372 public void testPollFirst() {
373 ConcurrentLinkedDeque q = populatedDeque(SIZE);
374 for (int i = 0; i < SIZE; ++i) {
375 assertEquals(i, q.pollFirst());
376 }
377 assertNull(q.pollFirst());
378 }
379
380 /**
381 * pollLast() succeeds unless empty
382 */
383 public void testPollLast() {
384 ConcurrentLinkedDeque q = populatedDeque(SIZE);
385 for (int i = SIZE - 1; i >= 0; --i) {
386 assertEquals(i, q.pollLast());
387 }
388 assertNull(q.pollLast());
389 }
390
391 /**
392 * poll() succeeds unless empty
393 */
394 public void testPoll() {
395 ConcurrentLinkedDeque q = populatedDeque(SIZE);
396 for (int i = 0; i < SIZE; ++i) {
397 assertEquals(i, q.poll());
398 }
399 assertNull(q.poll());
400 }
401
402 /**
403 * peek() returns next element, or null if empty
404 */
405 public void testPeek() {
406 ConcurrentLinkedDeque q = populatedDeque(SIZE);
407 for (int i = 0; i < SIZE; ++i) {
408 assertEquals(i, q.peek());
409 assertEquals(i, q.poll());
410 assertTrue(q.peek() == null ||
411 !q.peek().equals(i));
412 }
413 assertNull(q.peek());
414 }
415
416 /**
417 * element() returns first element, or throws NSEE if empty
418 */
419 public void testElement() {
420 ConcurrentLinkedDeque q = populatedDeque(SIZE);
421 for (int i = 0; i < SIZE; ++i) {
422 assertEquals(i, q.element());
423 assertEquals(i, q.poll());
424 }
425 try {
426 q.element();
427 shouldThrow();
428 } catch (NoSuchElementException success) {}
429 }
430
431 /**
432 * remove() removes next element, or throws NSEE if empty
433 */
434 public void testRemove() {
435 ConcurrentLinkedDeque q = populatedDeque(SIZE);
436 for (int i = 0; i < SIZE; ++i) {
437 assertEquals(i, q.remove());
438 }
439 try {
440 q.remove();
441 shouldThrow();
442 } catch (NoSuchElementException success) {}
443 }
444
445 /**
446 * remove(x) removes x and returns true if present
447 */
448 public void testRemoveElement() {
449 ConcurrentLinkedDeque q = populatedDeque(SIZE);
450 for (int i = 1; i < SIZE; i += 2) {
451 assertTrue(q.contains(i));
452 assertTrue(q.remove(i));
453 assertFalse(q.contains(i));
454 assertTrue(q.contains(i - 1));
455 }
456 for (int i = 0; i < SIZE; i += 2) {
457 assertTrue(q.contains(i));
458 assertTrue(q.remove(i));
459 assertFalse(q.contains(i));
460 assertFalse(q.remove(i + 1));
461 assertFalse(q.contains(i + 1));
462 }
463 assertTrue(q.isEmpty());
464 }
465
466 /**
467 * peekFirst() returns next element, or null if empty
468 */
469 public void testPeekFirst() {
470 ConcurrentLinkedDeque q = populatedDeque(SIZE);
471 for (int i = 0; i < SIZE; ++i) {
472 assertEquals(i, q.peekFirst());
473 assertEquals(i, q.pollFirst());
474 assertTrue(q.peekFirst() == null ||
475 !q.peekFirst().equals(i));
476 }
477 assertNull(q.peekFirst());
478 }
479
480 /**
481 * peekLast() returns next element, or null if empty
482 */
483 public void testPeekLast() {
484 ConcurrentLinkedDeque q = populatedDeque(SIZE);
485 for (int i = SIZE - 1; i >= 0; --i) {
486 assertEquals(i, q.peekLast());
487 assertEquals(i, q.pollLast());
488 assertTrue(q.peekLast() == null ||
489 !q.peekLast().equals(i));
490 }
491 assertNull(q.peekLast());
492 }
493
494 /**
495 * getFirst() returns first element, or throws NSEE if empty
496 */
497 public void testFirstElement() {
498 ConcurrentLinkedDeque q = populatedDeque(SIZE);
499 for (int i = 0; i < SIZE; ++i) {
500 assertEquals(i, q.getFirst());
501 assertEquals(i, q.pollFirst());
502 }
503 try {
504 q.getFirst();
505 shouldThrow();
506 } catch (NoSuchElementException success) {}
507 }
508
509 /**
510 * getLast() returns last element, or throws NSEE if empty
511 */
512 public void testLastElement() {
513 ConcurrentLinkedDeque q = populatedDeque(SIZE);
514 for (int i = SIZE - 1; i >= 0; --i) {
515 assertEquals(i, q.getLast());
516 assertEquals(i, q.pollLast());
517 }
518 try {
519 q.getLast();
520 shouldThrow();
521 } catch (NoSuchElementException success) {}
522 assertNull(q.peekLast());
523 }
524
525 /**
526 * removeFirst() removes first element, or throws NSEE if empty
527 */
528 public void testRemoveFirst() {
529 ConcurrentLinkedDeque q = populatedDeque(SIZE);
530 for (int i = 0; i < SIZE; ++i) {
531 assertEquals(i, q.removeFirst());
532 }
533 try {
534 q.removeFirst();
535 shouldThrow();
536 } catch (NoSuchElementException success) {}
537 assertNull(q.peekFirst());
538 }
539
540 /**
541 * removeLast() removes last element, or throws NSEE if empty
542 */
543 public void testRemoveLast() {
544 ConcurrentLinkedDeque q = populatedDeque(SIZE);
545 for (int i = SIZE - 1; i >= 0; --i) {
546 assertEquals(i, q.removeLast());
547 }
548 try {
549 q.removeLast();
550 shouldThrow();
551 } catch (NoSuchElementException success) {}
552 assertNull(q.peekLast());
553 }
554
555 /**
556 * removeFirstOccurrence(x) removes x and returns true if present
557 */
558 public void testRemoveFirstOccurrence() {
559 ConcurrentLinkedDeque q = populatedDeque(SIZE);
560 for (int i = 1; i < SIZE; i += 2) {
561 assertTrue(q.removeFirstOccurrence(new Integer(i)));
562 }
563 for (int i = 0; i < SIZE; i += 2) {
564 assertTrue(q.removeFirstOccurrence(new Integer(i)));
565 assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
566 }
567 assertTrue(q.isEmpty());
568 }
569
570 /**
571 * removeLastOccurrence(x) removes x and returns true if present
572 */
573 public void testRemoveLastOccurrence() {
574 ConcurrentLinkedDeque q = populatedDeque(SIZE);
575 for (int i = 1; i < SIZE; i += 2) {
576 assertTrue(q.removeLastOccurrence(new Integer(i)));
577 }
578 for (int i = 0; i < SIZE; i += 2) {
579 assertTrue(q.removeLastOccurrence(new Integer(i)));
580 assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
581 }
582 assertTrue(q.isEmpty());
583 }
584
585 /**
586 * contains(x) reports true when elements added but not yet removed
587 */
588 public void testContains() {
589 ConcurrentLinkedDeque q = populatedDeque(SIZE);
590 for (int i = 0; i < SIZE; ++i) {
591 assertTrue(q.contains(new Integer(i)));
592 q.poll();
593 assertFalse(q.contains(new Integer(i)));
594 }
595 }
596
597 /**
598 * clear() removes all elements
599 */
600 public void testClear() {
601 ConcurrentLinkedDeque q = populatedDeque(SIZE);
602 q.clear();
603 assertTrue(q.isEmpty());
604 assertEquals(0, q.size());
605 q.add(one);
606 assertFalse(q.isEmpty());
607 q.clear();
608 assertTrue(q.isEmpty());
609 }
610
611 /**
612 * containsAll(c) is true when c contains a subset of elements
613 */
614 public void testContainsAll() {
615 ConcurrentLinkedDeque q = populatedDeque(SIZE);
616 ConcurrentLinkedDeque p = new ConcurrentLinkedDeque();
617 for (int i = 0; i < SIZE; ++i) {
618 assertTrue(q.containsAll(p));
619 assertFalse(p.containsAll(q));
620 p.add(new Integer(i));
621 }
622 assertTrue(p.containsAll(q));
623 }
624
625 /**
626 * retainAll(c) retains only those elements of c and reports true if change
627 */
628 public void testRetainAll() {
629 ConcurrentLinkedDeque q = populatedDeque(SIZE);
630 ConcurrentLinkedDeque p = populatedDeque(SIZE);
631 for (int i = 0; i < SIZE; ++i) {
632 boolean changed = q.retainAll(p);
633 if (i == 0)
634 assertFalse(changed);
635 else
636 assertTrue(changed);
637
638 assertTrue(q.containsAll(p));
639 assertEquals(SIZE - i, q.size());
640 p.remove();
641 }
642 }
643
644 /**
645 * removeAll(c) removes only those elements of c and reports true if changed
646 */
647 public void testRemoveAll() {
648 for (int i = 1; i < SIZE; ++i) {
649 ConcurrentLinkedDeque q = populatedDeque(SIZE);
650 ConcurrentLinkedDeque p = populatedDeque(i);
651 assertTrue(q.removeAll(p));
652 assertEquals(SIZE - i, q.size());
653 for (int j = 0; j < i; ++j) {
654 Integer x = (Integer)(p.remove());
655 assertFalse(q.contains(x));
656 }
657 }
658 }
659
660 /**
661 * toArray() contains all elements in FIFO order
662 */
663 public void testToArray() {
664 ConcurrentLinkedDeque q = populatedDeque(SIZE);
665 Object[] a = q.toArray();
666 assertSame(Object[].class, a.getClass());
667 for (Object o : a)
668 assertSame(o, q.poll());
669 assertTrue(q.isEmpty());
670 }
671
672 /**
673 * toArray(a) contains all elements in FIFO order
674 */
675 public void testToArray2() {
676 ConcurrentLinkedDeque<Integer> q = populatedDeque(SIZE);
677 Integer[] ints = new Integer[SIZE];
678 Integer[] array = q.toArray(ints);
679 assertSame(ints, array);
680 for (Integer o : ints)
681 assertSame(o, q.poll());
682 assertTrue(q.isEmpty());
683 }
684
685 /**
686 * toArray(null) throws NullPointerException
687 */
688 public void testToArray_NullArg() {
689 ConcurrentLinkedDeque q = populatedDeque(SIZE);
690 try {
691 q.toArray((Object[])null);
692 shouldThrow();
693 } catch (NullPointerException success) {}
694 }
695
696 /**
697 * toArray(incompatible array type) throws ArrayStoreException
698 */
699 public void testToArray1_BadArg() {
700 ConcurrentLinkedDeque q = populatedDeque(SIZE);
701 try {
702 q.toArray(new String[10]);
703 shouldThrow();
704 } catch (ArrayStoreException success) {}
705 }
706
707 /**
708 * Iterator iterates through all elements
709 */
710 public void testIterator() {
711 ConcurrentLinkedDeque q = populatedDeque(SIZE);
712 Iterator it = q.iterator();
713 int i;
714 for (i = 0; it.hasNext(); i++)
715 assertTrue(q.contains(it.next()));
716 assertEquals(i, SIZE);
717 assertIteratorExhausted(it);
718 }
719
720 /**
721 * iterator of empty collection has no elements
722 */
723 public void testEmptyIterator() {
724 Deque c = new ConcurrentLinkedDeque();
725 assertIteratorExhausted(c.iterator());
726 assertIteratorExhausted(c.descendingIterator());
727 }
728
729 /**
730 * Iterator ordering is FIFO
731 */
732 public void testIteratorOrdering() {
733 final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
734 q.add(one);
735 q.add(two);
736 q.add(three);
737
738 int k = 0;
739 for (Iterator it = q.iterator(); it.hasNext();) {
740 assertEquals(++k, it.next());
741 }
742
743 assertEquals(3, k);
744 }
745
746 /**
747 * Modifications do not cause iterators to fail
748 */
749 public void testWeaklyConsistentIteration() {
750 final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
751 q.add(one);
752 q.add(two);
753 q.add(three);
754
755 for (Iterator it = q.iterator(); it.hasNext();) {
756 q.remove();
757 it.next();
758 }
759
760 assertEquals("deque should be empty again", 0, q.size());
761 }
762
763 /**
764 * iterator.remove() removes current element
765 */
766 public void testIteratorRemove() {
767 final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
768 final Random rng = new Random();
769 for (int iters = 0; iters < 100; ++iters) {
770 int max = rng.nextInt(5) + 2;
771 int split = rng.nextInt(max - 1) + 1;
772 for (int j = 1; j <= max; ++j)
773 q.add(new Integer(j));
774 Iterator it = q.iterator();
775 for (int j = 1; j <= split; ++j)
776 assertEquals(it.next(), new Integer(j));
777 it.remove();
778 assertEquals(it.next(), new Integer(split + 1));
779 for (int j = 1; j <= split; ++j)
780 q.remove(new Integer(j));
781 it = q.iterator();
782 for (int j = split + 1; j <= max; ++j) {
783 assertEquals(it.next(), new Integer(j));
784 it.remove();
785 }
786 assertFalse(it.hasNext());
787 assertTrue(q.isEmpty());
788 }
789 }
790
791 /**
792 * Descending iterator iterates through all elements
793 */
794 public void testDescendingIterator() {
795 ConcurrentLinkedDeque q = populatedDeque(SIZE);
796 int i = 0;
797 Iterator it = q.descendingIterator();
798 while (it.hasNext()) {
799 assertTrue(q.contains(it.next()));
800 ++i;
801 }
802 assertEquals(i, SIZE);
803 assertFalse(it.hasNext());
804 try {
805 it.next();
806 shouldThrow();
807 } catch (NoSuchElementException success) {}
808 }
809
810 /**
811 * Descending iterator ordering is reverse FIFO
812 */
813 public void testDescendingIteratorOrdering() {
814 final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
815 for (int iters = 0; iters < 100; ++iters) {
816 q.add(new Integer(3));
817 q.add(new Integer(2));
818 q.add(new Integer(1));
819 int k = 0;
820 for (Iterator it = q.descendingIterator(); it.hasNext();) {
821 assertEquals(++k, it.next());
822 }
823
824 assertEquals(3, k);
825 q.remove();
826 q.remove();
827 q.remove();
828 }
829 }
830
831 /**
832 * descendingIterator.remove() removes current element
833 */
834 public void testDescendingIteratorRemove() {
835 final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
836 final Random rng = new Random();
837 for (int iters = 0; iters < 100; ++iters) {
838 int max = rng.nextInt(5) + 2;
839 int split = rng.nextInt(max - 1) + 1;
840 for (int j = max; j >= 1; --j)
841 q.add(new Integer(j));
842 Iterator it = q.descendingIterator();
843 for (int j = 1; j <= split; ++j)
844 assertEquals(it.next(), new Integer(j));
845 it.remove();
846 assertEquals(it.next(), new Integer(split + 1));
847 for (int j = 1; j <= split; ++j)
848 q.remove(new Integer(j));
849 it = q.descendingIterator();
850 for (int j = split + 1; j <= max; ++j) {
851 assertEquals(it.next(), new Integer(j));
852 it.remove();
853 }
854 assertFalse(it.hasNext());
855 assertTrue(q.isEmpty());
856 }
857 }
858
859 /**
860 * toString() contains toStrings of elements
861 */
862 public void testToString() {
863 ConcurrentLinkedDeque q = populatedDeque(SIZE);
864 String s = q.toString();
865 for (int i = 0; i < SIZE; ++i) {
866 assertTrue(s.contains(String.valueOf(i)));
867 }
868 }
869
870 /**
871 * A deserialized/reserialized deque has same elements in same order
872 */
873 public void testSerialization() throws Exception {
874 Queue x = populatedDeque(SIZE);
875 Queue y = serialClone(x);
876
877 assertNotSame(x, y);
878 assertEquals(x.size(), y.size());
879 assertEquals(x.toString(), y.toString());
880 assertTrue(Arrays.equals(x.toArray(), y.toArray()));
881 while (!x.isEmpty()) {
882 assertFalse(y.isEmpty());
883 assertEquals(x.remove(), y.remove());
884 }
885 assertTrue(y.isEmpty());
886 }
887
888 /**
889 * contains(null) always return false.
890 * remove(null) always throws NullPointerException.
891 */
892 public void testNeverContainsNull() {
893 Deque<?>[] qs = {
894 new ConcurrentLinkedDeque<Object>(),
895 populatedDeque(2),
896 };
897
898 for (Deque<?> q : qs) {
899 assertFalse(q.contains(null));
900 try {
901 assertFalse(q.remove(null));
902 shouldThrow();
903 } catch (NullPointerException success) {}
904 try {
905 assertFalse(q.removeFirstOccurrence(null));
906 shouldThrow();
907 } catch (NullPointerException success) {}
908 try {
909 assertFalse(q.removeLastOccurrence(null));
910 shouldThrow();
911 } catch (NullPointerException success) {}
912 }
913 }
914
915 void runAsync(Runnable r1, Runnable r2) {
916 boolean b = randomBoolean();
917 CompletableFuture<Void> f1 = CompletableFuture.runAsync(b ? r1 : r2);
918 CompletableFuture<Void> f2 = CompletableFuture.runAsync(b ? r2 : r1);
919 f1.join();
920 f2.join();
921 }
922
923 /**
924 * Non-traversing Deque operations are linearizable.
925 * https://bugs.openjdk.java.net/browse/JDK-8188900
926 * ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8188900 tck
927 */
928 public void testBug8188900() {
929 final ThreadLocalRandom rnd = ThreadLocalRandom.current();
930 final LongAdder nulls = new LongAdder(), zeros = new LongAdder();
931 for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) {
932 ConcurrentLinkedDeque<Integer> d = new ConcurrentLinkedDeque<>();
933
934 boolean peek = rnd.nextBoolean();
935 Runnable getter = () -> {
936 Integer x = peek ? d.peekFirst() : d.pollFirst();
937 if (x == null) nulls.increment();
938 else if (x == 0) zeros.increment();
939 else
940 throw new AssertionError(
941 String.format(
942 "unexpected value %d after %d nulls and %d zeros",
943 x, nulls.sum(), zeros.sum()));
944 };
945
946 Runnable adder = () -> { d.addFirst(0); d.addLast(42); };
947
948 runAsync(getter, adder);
949 }
950 }
951
952 /**
953 * Reverse direction variant of testBug8188900
954 */
955 public void testBug8188900_reverse() {
956 final ThreadLocalRandom rnd = ThreadLocalRandom.current();
957 final LongAdder nulls = new LongAdder(), zeros = new LongAdder();
958 for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) {
959 ConcurrentLinkedDeque<Integer> d = new ConcurrentLinkedDeque<>();
960
961 boolean peek = rnd.nextBoolean();
962 Runnable getter = () -> {
963 Integer x = peek ? d.peekLast() : d.pollLast();
964 if (x == null) nulls.increment();
965 else if (x == 0) zeros.increment();
966 else
967 throw new AssertionError(
968 String.format(
969 "unexpected value %d after %d nulls and %d zeros",
970 x, nulls.sum(), zeros.sum()));
971 };
972
973 Runnable adder = () -> { d.addLast(0); d.addFirst(42); };
974
975 runAsync(getter, adder);
976 }
977 }
978
979 /**
980 * Non-traversing Deque operations (that return null) are linearizable.
981 * Don't return null when the deque is observably never empty.
982 * https://bugs.openjdk.java.net/browse/JDK-8189387
983 * ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8189387 tck
984 */
985 public void testBug8189387() {
986 final ThreadLocalRandom rnd = ThreadLocalRandom.current();
987 Object x = new Object();
988 for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) {
989 ConcurrentLinkedDeque<Object> d = new ConcurrentLinkedDeque<>();
990 Runnable add = chooseRandomly(
991 () -> d.addFirst(x),
992 () -> d.offerFirst(x),
993 () -> d.addLast(x),
994 () -> d.offerLast(x));
995
996 Runnable get = chooseRandomly(
997 () -> assertFalse(d.isEmpty()),
998 () -> assertSame(x, d.peekFirst()),
999 () -> assertSame(x, d.peekLast()),
1000 () -> assertSame(x, d.pollFirst()),
1001 () -> assertSame(x, d.pollLast()));
1002
1003 Runnable addRemove = chooseRandomly(
1004 () -> { d.addFirst(x); d.pollLast(); },
1005 () -> { d.offerFirst(x); d.removeFirst(); },
1006 () -> { d.offerLast(x); d.removeLast(); },
1007 () -> { d.addLast(x); d.pollFirst(); });
1008
1009 add.run();
1010 runAsync(get, addRemove);
1011 }
1012 }
1013 }