1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea with assistance from members of JCP JSR-166 30 * Expert Group and released to the public domain, as explained at 31 * http://creativecommons.org/publicdomain/zero/1.0/ 32 * Other contributors include Andrew Wright, Jeffrey Hayes, 33 * Pat Fisher, Mike Judd. 34 */ 35 36 import static java.util.concurrent.TimeUnit.MILLISECONDS; 37 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.Collection; 41 import java.util.Collections; 42 import java.util.Iterator; 43 import java.util.NoSuchElementException; 44 import java.util.Queue; 45 import java.util.concurrent.ArrayBlockingQueue; 46 import java.util.concurrent.BlockingQueue; 47 import java.util.concurrent.CountDownLatch; 48 import java.util.concurrent.Executors; 49 import java.util.concurrent.ExecutorService; 50 import java.util.concurrent.ThreadLocalRandom; 51 52 import junit.framework.Test; 53 54 public class ArrayBlockingQueueTest extends JSR166TestCase { 55 56 public static void main(String[] args) { 57 main(suite(), args); 58 } 59 60 public static Test suite() { 61 class Implementation implements CollectionImplementation { 62 public Class<?> klazz() { return ArrayBlockingQueue.class; } 63 public Collection emptyCollection() { 64 boolean fair = randomBoolean(); 65 return populatedQueue(0, SIZE, 2 * SIZE, fair); 66 } 67 public Object makeElement(int i) { return i; } 68 public boolean isConcurrent() { return true; } 69 public boolean permitsNulls() { return false; } 70 } 71 72 return newTestSuite( 73 ArrayBlockingQueueTest.class, 74 new Fair().testSuite(), 75 new NonFair().testSuite(), 76 CollectionTest.testSuite(new Implementation())); 77 } 78 79 public static class Fair extends BlockingQueueTest { 80 protected BlockingQueue emptyCollection() { 81 return populatedQueue(0, SIZE, 2 * SIZE, true); 82 } 83 } 84 85 public static class NonFair extends BlockingQueueTest { 86 protected BlockingQueue emptyCollection() { 87 return populatedQueue(0, SIZE, 2 * SIZE, false); 88 } 89 } 90 91 /** 92 * Returns a new queue of given size containing consecutive 93 * Integers 0 ... n - 1. 94 */ 95 static ArrayBlockingQueue<Integer> populatedQueue(int n) { 96 return populatedQueue(n, n, n, false); 97 } 98 99 /** 100 * Returns a new queue of given size containing consecutive 101 * Integers 0 ... n - 1, with given capacity range and fairness. 102 */ 103 static ArrayBlockingQueue<Integer> populatedQueue( 104 int size, int minCapacity, int maxCapacity, boolean fair) { 105 ThreadLocalRandom rnd = ThreadLocalRandom.current(); 106 int capacity = rnd.nextInt(minCapacity, maxCapacity + 1); 107 ArrayBlockingQueue<Integer> q = new ArrayBlockingQueue<>(capacity); 108 assertTrue(q.isEmpty()); 109 // shuffle circular array elements so they wrap 110 { 111 int n = rnd.nextInt(capacity); 112 for (int i = 0; i < n; i++) q.add(42); 113 for (int i = 0; i < n; i++) q.remove(); 114 } 115 for (int i = 0; i < size; i++) 116 assertTrue(q.offer((Integer) i)); 117 assertEquals(size == 0, q.isEmpty()); 118 assertEquals(capacity - size, q.remainingCapacity()); 119 assertEquals(size, q.size()); 120 if (size > 0) 121 assertEquals((Integer) 0, q.peek()); 122 return q; 123 } 124 125 /** 126 * A new queue has the indicated capacity 127 */ 128 public void testConstructor1() { 129 assertEquals(SIZE, new ArrayBlockingQueue(SIZE).remainingCapacity()); 130 } 131 132 /** 133 * Constructor throws IllegalArgumentException if capacity argument nonpositive 134 */ 135 public void testConstructor_nonPositiveCapacity() { 136 for (int i : new int[] { 0, -1, Integer.MIN_VALUE }) { 137 try { 138 new ArrayBlockingQueue(i); 139 shouldThrow(); 140 } catch (IllegalArgumentException success) {} 141 for (boolean fair : new boolean[] { true, false }) { 142 try { 143 new ArrayBlockingQueue(i, fair); 144 shouldThrow(); 145 } catch (IllegalArgumentException success) {} 146 } 147 } 148 } 149 150 /** 151 * Initializing from null Collection throws NPE 152 */ 153 public void testConstructor_nullCollection() { 154 try { 155 new ArrayBlockingQueue(1, true, null); 156 shouldThrow(); 157 } catch (NullPointerException success) {} 158 } 159 160 /** 161 * Initializing from Collection of null elements throws NPE 162 */ 163 public void testConstructor4() { 164 Collection<Integer> elements = Arrays.asList(new Integer[SIZE]); 165 try { 166 new ArrayBlockingQueue(SIZE, false, elements); 167 shouldThrow(); 168 } catch (NullPointerException success) {} 169 } 170 171 /** 172 * Initializing from Collection with some null elements throws NPE 173 */ 174 public void testConstructor5() { 175 Integer[] ints = new Integer[SIZE]; 176 for (int i = 0; i < SIZE - 1; ++i) 177 ints[i] = i; 178 Collection<Integer> elements = Arrays.asList(ints); 179 try { 180 new ArrayBlockingQueue(SIZE, false, elements); 181 shouldThrow(); 182 } catch (NullPointerException success) {} 183 } 184 185 /** 186 * Initializing from too large collection throws IllegalArgumentException 187 */ 188 public void testConstructor_collectionTooLarge() { 189 // just barely fits - succeeds 190 new ArrayBlockingQueue(SIZE, false, 191 Collections.nCopies(SIZE, "")); 192 try { 193 new ArrayBlockingQueue(SIZE - 1, false, 194 Collections.nCopies(SIZE, "")); 195 shouldThrow(); 196 } catch (IllegalArgumentException success) {} 197 } 198 199 /** 200 * Queue contains all elements of collection used to initialize 201 */ 202 public void testConstructor7() { 203 Integer[] ints = new Integer[SIZE]; 204 for (int i = 0; i < SIZE; ++i) 205 ints[i] = i; 206 Collection<Integer> elements = Arrays.asList(ints); 207 ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, true, elements); 208 for (int i = 0; i < SIZE; ++i) 209 assertEquals(ints[i], q.poll()); 210 } 211 212 /** 213 * Queue transitions from empty to full when elements added 214 */ 215 public void testEmptyFull() { 216 BlockingQueue q = populatedQueue(0, 2, 2, false); 217 assertTrue(q.isEmpty()); 218 assertEquals(2, q.remainingCapacity()); 219 q.add(one); 220 assertFalse(q.isEmpty()); 221 assertTrue(q.offer(two)); 222 assertFalse(q.isEmpty()); 223 assertEquals(0, q.remainingCapacity()); 224 assertFalse(q.offer(three)); 225 } 226 227 /** 228 * remainingCapacity decreases on add, increases on remove 229 */ 230 public void testRemainingCapacity() { 231 int size = ThreadLocalRandom.current().nextInt(1, SIZE); 232 BlockingQueue q = populatedQueue(size, size, 2 * size, false); 233 int spare = q.remainingCapacity(); 234 int capacity = spare + size; 235 for (int i = 0; i < size; i++) { 236 assertEquals(spare + i, q.remainingCapacity()); 237 assertEquals(capacity, q.size() + q.remainingCapacity()); 238 assertEquals(i, q.remove()); 239 } 240 for (int i = 0; i < size; i++) { 241 assertEquals(capacity - i, q.remainingCapacity()); 242 assertEquals(capacity, q.size() + q.remainingCapacity()); 243 assertTrue(q.add(i)); 244 } 245 } 246 247 /** 248 * Offer succeeds if not full; fails if full 249 */ 250 public void testOffer() { 251 ArrayBlockingQueue q = new ArrayBlockingQueue(1); 252 assertTrue(q.offer(zero)); 253 assertFalse(q.offer(one)); 254 } 255 256 /** 257 * add succeeds if not full; throws IllegalStateException if full 258 */ 259 public void testAdd() { 260 ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); 261 for (int i = 0; i < SIZE; i++) assertTrue(q.add((Integer) i)); 262 assertEquals(0, q.remainingCapacity()); 263 try { 264 q.add((Integer) SIZE); 265 shouldThrow(); 266 } catch (IllegalStateException success) {} 267 } 268 269 /** 270 * addAll(this) throws IllegalArgumentException 271 */ 272 public void testAddAllSelf() { 273 ArrayBlockingQueue q = populatedQueue(SIZE); 274 try { 275 q.addAll(q); 276 shouldThrow(); 277 } catch (IllegalArgumentException success) {} 278 } 279 280 /** 281 * addAll of a collection with any null elements throws NPE after 282 * possibly adding some elements 283 */ 284 public void testAddAll3() { 285 ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); 286 Integer[] ints = new Integer[SIZE]; 287 for (int i = 0; i < SIZE - 1; ++i) 288 ints[i] = new Integer(i); 289 try { 290 q.addAll(Arrays.asList(ints)); 291 shouldThrow(); 292 } catch (NullPointerException success) {} 293 } 294 295 /** 296 * addAll throws IllegalStateException if not enough room 297 */ 298 public void testAddAll_insufficientSpace() { 299 int size = ThreadLocalRandom.current().nextInt(1, SIZE); 300 ArrayBlockingQueue q = populatedQueue(0, size, size, false); 301 // Just fits: 302 q.addAll(populatedQueue(size, size, 2 * size, false)); 303 assertEquals(0, q.remainingCapacity()); 304 assertEquals(size, q.size()); 305 assertEquals(0, q.peek()); 306 try { 307 q = populatedQueue(0, size, size, false); 308 q.addAll(Collections.nCopies(size + 1, 42)); 309 shouldThrow(); 310 } catch (IllegalStateException success) {} 311 } 312 313 /** 314 * Queue contains all elements, in traversal order, of successful addAll 315 */ 316 public void testAddAll5() { 317 Integer[] empty = new Integer[0]; 318 Integer[] ints = new Integer[SIZE]; 319 for (int i = 0; i < SIZE; ++i) 320 ints[i] = new Integer(i); 321 ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); 322 assertFalse(q.addAll(Arrays.asList(empty))); 323 assertTrue(q.addAll(Arrays.asList(ints))); 324 for (int i = 0; i < SIZE; ++i) 325 assertEquals(ints[i], q.poll()); 326 } 327 328 /** 329 * all elements successfully put are contained 330 */ 331 public void testPut() throws InterruptedException { 332 ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); 333 for (int i = 0; i < SIZE; ++i) { 334 Integer x = new Integer(i); 335 q.put(x); 336 assertTrue(q.contains(x)); 337 } 338 assertEquals(0, q.remainingCapacity()); 339 } 340 341 /** 342 * put blocks interruptibly if full 343 */ 344 public void testBlockingPut() throws InterruptedException { 345 final ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE); 346 final CountDownLatch pleaseInterrupt = new CountDownLatch(1); 347 Thread t = newStartedThread(new CheckedRunnable() { 348 public void realRun() throws InterruptedException { 349 for (int i = 0; i < SIZE; ++i) 350 q.put(i); 351 assertEquals(SIZE, q.size()); 352 assertEquals(0, q.remainingCapacity()); 353 354 Thread.currentThread().interrupt(); 355 try { 356 q.put(99); 357 shouldThrow(); 358 } catch (InterruptedException success) {} 359 assertFalse(Thread.interrupted()); 360 361 pleaseInterrupt.countDown(); 362 try { 363 q.put(99); 364 shouldThrow(); 365 } catch (InterruptedException success) {} 366 assertFalse(Thread.interrupted()); 367 }}); 368 369 await(pleaseInterrupt); 370 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); 371 t.interrupt(); 372 awaitTermination(t); 373 assertEquals(SIZE, q.size()); 374 assertEquals(0, q.remainingCapacity()); 375 } 376 377 /** 378 * put blocks interruptibly waiting for take when full 379 */ 380 public void testPutWithTake() throws InterruptedException { 381 final int capacity = 2; 382 final ArrayBlockingQueue q = new ArrayBlockingQueue(capacity); 383 final CountDownLatch pleaseTake = new CountDownLatch(1); 384 final CountDownLatch pleaseInterrupt = new CountDownLatch(1); 385 Thread t = newStartedThread(new CheckedRunnable() { 386 public void realRun() throws InterruptedException { 387 for (int i = 0; i < capacity; i++) 388 q.put(i); 389 pleaseTake.countDown(); 390 q.put(86); 391 392 Thread.currentThread().interrupt(); 393 try { 394 q.put(99); 395 shouldThrow(); 396 } catch (InterruptedException success) {} 397 assertFalse(Thread.interrupted()); 398 399 pleaseInterrupt.countDown(); 400 try { 401 q.put(99); 402 shouldThrow(); 403 } catch (InterruptedException success) {} 404 assertFalse(Thread.interrupted()); 405 }}); 406 407 await(pleaseTake); 408 assertEquals(0, q.remainingCapacity()); 409 assertEquals(0, q.take()); 410 411 await(pleaseInterrupt); 412 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); 413 t.interrupt(); 414 awaitTermination(t); 415 assertEquals(0, q.remainingCapacity()); 416 } 417 418 /** 419 * timed offer times out if full and elements not taken 420 */ 421 public void testTimedOffer() { 422 final ArrayBlockingQueue q = new ArrayBlockingQueue(2); 423 final CountDownLatch pleaseInterrupt = new CountDownLatch(1); 424 Thread t = newStartedThread(new CheckedRunnable() { 425 public void realRun() throws InterruptedException { 426 q.put(new Object()); 427 q.put(new Object()); 428 long startTime = System.nanoTime(); 429 assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); 430 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 431 432 Thread.currentThread().interrupt(); 433 try { 434 q.offer(new Object(), randomTimeout(), randomTimeUnit()); 435 shouldThrow(); 436 } catch (InterruptedException success) {} 437 assertFalse(Thread.interrupted()); 438 439 pleaseInterrupt.countDown(); 440 try { 441 q.offer(new Object(), LONGER_DELAY_MS, MILLISECONDS); 442 shouldThrow(); 443 } catch (InterruptedException success) {} 444 assertFalse(Thread.interrupted()); 445 }}); 446 447 await(pleaseInterrupt); 448 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); 449 t.interrupt(); 450 awaitTermination(t); 451 } 452 453 /** 454 * take retrieves elements in FIFO order 455 */ 456 public void testTake() throws InterruptedException { 457 ArrayBlockingQueue q = populatedQueue(SIZE); 458 for (int i = 0; i < SIZE; ++i) { 459 assertEquals(i, q.take()); 460 } 461 } 462 463 /** 464 * Take removes existing elements until empty, then blocks interruptibly 465 */ 466 public void testBlockingTake() throws InterruptedException { 467 final ArrayBlockingQueue q = populatedQueue(SIZE); 468 final CountDownLatch pleaseInterrupt = new CountDownLatch(1); 469 Thread t = newStartedThread(new CheckedRunnable() { 470 public void realRun() throws InterruptedException { 471 for (int i = 0; i < SIZE; i++) assertEquals(i, q.take()); 472 473 Thread.currentThread().interrupt(); 474 try { 475 q.take(); 476 shouldThrow(); 477 } catch (InterruptedException success) {} 478 assertFalse(Thread.interrupted()); 479 480 pleaseInterrupt.countDown(); 481 try { 482 q.take(); 483 shouldThrow(); 484 } catch (InterruptedException success) {} 485 assertFalse(Thread.interrupted()); 486 }}); 487 488 await(pleaseInterrupt); 489 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); 490 t.interrupt(); 491 awaitTermination(t); 492 } 493 494 /** 495 * poll succeeds unless empty 496 */ 497 public void testPoll() { 498 ArrayBlockingQueue q = populatedQueue(SIZE); 499 for (int i = 0; i < SIZE; ++i) { 500 assertEquals(i, q.poll()); 501 } 502 assertNull(q.poll()); 503 } 504 505 /** 506 * timed poll with zero timeout succeeds when non-empty, else times out 507 */ 508 public void testTimedPoll0() throws InterruptedException { 509 ArrayBlockingQueue q = populatedQueue(SIZE); 510 for (int i = 0; i < SIZE; ++i) { 511 assertEquals(i, q.poll(0, MILLISECONDS)); 512 } 513 assertNull(q.poll(0, MILLISECONDS)); 514 checkEmpty(q); 515 } 516 517 /** 518 * timed poll with nonzero timeout succeeds when non-empty, else times out 519 */ 520 public void testTimedPoll() throws InterruptedException { 521 ArrayBlockingQueue q = populatedQueue(SIZE); 522 for (int i = 0; i < SIZE; ++i) { 523 long startTime = System.nanoTime(); 524 assertEquals(i, q.poll(LONG_DELAY_MS, MILLISECONDS)); 525 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); 526 } 527 long startTime = System.nanoTime(); 528 assertNull(q.poll(timeoutMillis(), MILLISECONDS)); 529 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 530 checkEmpty(q); 531 } 532 533 /** 534 * Interrupted timed poll throws InterruptedException instead of 535 * returning timeout status 536 */ 537 public void testInterruptedTimedPoll() throws InterruptedException { 538 final BlockingQueue<Integer> q = populatedQueue(SIZE); 539 final CountDownLatch pleaseInterrupt = new CountDownLatch(1); 540 Thread t = newStartedThread(new CheckedRunnable() { 541 public void realRun() throws InterruptedException { 542 for (int i = 0; i < SIZE; i++) 543 assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); 544 545 Thread.currentThread().interrupt(); 546 try { 547 q.poll(randomTimeout(), randomTimeUnit()); 548 shouldThrow(); 549 } catch (InterruptedException success) {} 550 assertFalse(Thread.interrupted()); 551 552 pleaseInterrupt.countDown(); 553 try { 554 q.poll(LONGER_DELAY_MS, MILLISECONDS); 555 shouldThrow(); 556 } catch (InterruptedException success) {} 557 assertFalse(Thread.interrupted()); 558 }}); 559 560 await(pleaseInterrupt); 561 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); 562 t.interrupt(); 563 awaitTermination(t); 564 checkEmpty(q); 565 } 566 567 /** 568 * peek returns next element, or null if empty 569 */ 570 public void testPeek() { 571 ArrayBlockingQueue q = populatedQueue(SIZE); 572 for (int i = 0; i < SIZE; ++i) { 573 assertEquals(i, q.peek()); 574 assertEquals(i, q.poll()); 575 assertTrue(q.peek() == null || 576 !q.peek().equals(i)); 577 } 578 assertNull(q.peek()); 579 } 580 581 /** 582 * element returns next element, or throws NSEE if empty 583 */ 584 public void testElement() { 585 ArrayBlockingQueue q = populatedQueue(SIZE); 586 for (int i = 0; i < SIZE; ++i) { 587 assertEquals(i, q.element()); 588 assertEquals(i, q.poll()); 589 } 590 try { 591 q.element(); 592 shouldThrow(); 593 } catch (NoSuchElementException success) {} 594 } 595 596 /** 597 * remove removes next element, or throws NSEE if empty 598 */ 599 public void testRemove() { 600 ArrayBlockingQueue q = populatedQueue(SIZE); 601 for (int i = 0; i < SIZE; ++i) { 602 assertEquals(i, q.remove()); 603 } 604 try { 605 q.remove(); 606 shouldThrow(); 607 } catch (NoSuchElementException success) {} 608 } 609 610 /** 611 * contains(x) reports true when elements added but not yet removed 612 */ 613 public void testContains() { 614 int size = ThreadLocalRandom.current().nextInt(1, SIZE); 615 ArrayBlockingQueue q = populatedQueue(size, size, 2 * size, false); 616 assertFalse(q.contains(null)); 617 for (int i = 0; i < size; ++i) { 618 assertTrue(q.contains(new Integer(i))); 619 assertEquals(i, q.poll()); 620 assertFalse(q.contains(new Integer(i))); 621 } 622 } 623 624 /** 625 * clear removes all elements 626 */ 627 public void testClear() { 628 int size = ThreadLocalRandom.current().nextInt(1, 5); 629 ArrayBlockingQueue q = populatedQueue(size, size, 2 * size, false); 630 int capacity = size + q.remainingCapacity(); 631 q.clear(); 632 assertTrue(q.isEmpty()); 633 assertEquals(0, q.size()); 634 assertEquals(capacity, q.remainingCapacity()); 635 q.add(one); 636 assertFalse(q.isEmpty()); 637 assertTrue(q.contains(one)); 638 q.clear(); 639 assertTrue(q.isEmpty()); 640 } 641 642 /** 643 * containsAll(c) is true when c contains a subset of elements 644 */ 645 public void testContainsAll() { 646 ArrayBlockingQueue q = populatedQueue(SIZE); 647 ArrayBlockingQueue p = new ArrayBlockingQueue(SIZE); 648 for (int i = 0; i < SIZE; ++i) { 649 assertTrue(q.containsAll(p)); 650 assertFalse(p.containsAll(q)); 651 p.add(new Integer(i)); 652 } 653 assertTrue(p.containsAll(q)); 654 } 655 656 /** 657 * retainAll(c) retains only those elements of c and reports true if changed 658 */ 659 public void testRetainAll() { 660 ArrayBlockingQueue q = populatedQueue(SIZE); 661 ArrayBlockingQueue p = populatedQueue(SIZE); 662 for (int i = 0; i < SIZE; ++i) { 663 boolean changed = q.retainAll(p); 664 if (i == 0) 665 assertFalse(changed); 666 else 667 assertTrue(changed); 668 669 assertTrue(q.containsAll(p)); 670 assertEquals(SIZE - i, q.size()); 671 p.remove(); 672 } 673 } 674 675 /** 676 * removeAll(c) removes only those elements of c and reports true if changed 677 */ 678 public void testRemoveAll() { 679 for (int i = 1; i < SIZE; ++i) { 680 ArrayBlockingQueue q = populatedQueue(SIZE); 681 ArrayBlockingQueue p = populatedQueue(i); 682 assertTrue(q.removeAll(p)); 683 assertEquals(SIZE - i, q.size()); 684 for (int j = 0; j < i; ++j) { 685 Integer x = (Integer)(p.remove()); 686 assertFalse(q.contains(x)); 687 } 688 } 689 } 690 691 void checkToArray(ArrayBlockingQueue<Integer> q) { 692 int size = q.size(); 693 Object[] a1 = q.toArray(); 694 assertEquals(size, a1.length); 695 Integer[] a2 = q.toArray(new Integer[0]); 696 assertEquals(size, a2.length); 697 Integer[] a3 = q.toArray(new Integer[Math.max(0, size - 1)]); 698 assertEquals(size, a3.length); 699 Integer[] a4 = new Integer[size]; 700 assertSame(a4, q.toArray(a4)); 701 Integer[] a5 = new Integer[size + 1]; 702 Arrays.fill(a5, 42); 703 assertSame(a5, q.toArray(a5)); 704 Integer[] a6 = new Integer[size + 2]; 705 Arrays.fill(a6, 42); 706 assertSame(a6, q.toArray(a6)); 707 Object[][] as = { a1, a2, a3, a4, a5, a6 }; 708 for (Object[] a : as) { 709 if (a.length > size) assertNull(a[size]); 710 if (a.length > size + 1) assertEquals(42, a[size + 1]); 711 } 712 Iterator it = q.iterator(); 713 Integer s = q.peek(); 714 for (int i = 0; i < size; i++) { 715 Integer x = (Integer) it.next(); 716 assertEquals(s + i, (int) x); 717 for (Object[] a : as) 718 assertSame(a1[i], x); 719 } 720 } 721 722 /** 723 * toArray() and toArray(a) contain all elements in FIFO order 724 */ 725 public void testToArray() { 726 final ThreadLocalRandom rnd = ThreadLocalRandom.current(); 727 final int size = rnd.nextInt(6); 728 final int capacity = Math.max(1, size + rnd.nextInt(size + 1)); 729 ArrayBlockingQueue<Integer> q = new ArrayBlockingQueue<>(capacity); 730 for (int i = 0; i < size; i++) { 731 checkToArray(q); 732 q.add(i); 733 } 734 // Provoke wraparound 735 int added = size * 2; 736 for (int i = 0; i < added; i++) { 737 checkToArray(q); 738 assertEquals((Integer) i, q.poll()); 739 q.add(size + i); 740 } 741 for (int i = 0; i < size; i++) { 742 checkToArray(q); 743 assertEquals((Integer) (added + i), q.poll()); 744 } 745 } 746 747 /** 748 * toArray(incompatible array type) throws ArrayStoreException 749 */ 750 public void testToArray_incompatibleArrayType() { 751 ArrayBlockingQueue q = populatedQueue(SIZE); 752 try { 753 q.toArray(new String[10]); 754 shouldThrow(); 755 } catch (ArrayStoreException success) {} 756 try { 757 q.toArray(new String[0]); 758 shouldThrow(); 759 } catch (ArrayStoreException success) {} 760 } 761 762 /** 763 * iterator iterates through all elements 764 */ 765 public void testIterator() throws InterruptedException { 766 ArrayBlockingQueue q = populatedQueue(SIZE); 767 Iterator it = q.iterator(); 768 int i; 769 for (i = 0; it.hasNext(); i++) 770 assertTrue(q.contains(it.next())); 771 assertEquals(i, SIZE); 772 assertIteratorExhausted(it); 773 774 it = q.iterator(); 775 for (i = 0; it.hasNext(); i++) 776 assertEquals(it.next(), q.take()); 777 assertEquals(i, SIZE); 778 assertIteratorExhausted(it); 779 } 780 781 /** 782 * iterator of empty collection has no elements 783 */ 784 public void testEmptyIterator() { 785 assertIteratorExhausted(new ArrayBlockingQueue(SIZE).iterator()); 786 } 787 788 /** 789 * iterator.remove removes current element 790 */ 791 public void testIteratorRemove() { 792 final ArrayBlockingQueue q = new ArrayBlockingQueue(3); 793 q.add(two); 794 q.add(one); 795 q.add(three); 796 797 Iterator it = q.iterator(); 798 it.next(); 799 it.remove(); 800 801 it = q.iterator(); 802 assertSame(it.next(), one); 803 assertSame(it.next(), three); 804 assertFalse(it.hasNext()); 805 } 806 807 /** 808 * iterator ordering is FIFO 809 */ 810 public void testIteratorOrdering() { 811 final ArrayBlockingQueue q = new ArrayBlockingQueue(3); 812 q.add(one); 813 q.add(two); 814 q.add(three); 815 816 assertEquals("queue should be full", 0, q.remainingCapacity()); 817 818 int k = 0; 819 for (Iterator it = q.iterator(); it.hasNext();) { 820 assertEquals(++k, it.next()); 821 } 822 assertEquals(3, k); 823 } 824 825 /** 826 * Modifications do not cause iterators to fail 827 */ 828 public void testWeaklyConsistentIteration() { 829 final ArrayBlockingQueue q = new ArrayBlockingQueue(3); 830 q.add(one); 831 q.add(two); 832 q.add(three); 833 for (Iterator it = q.iterator(); it.hasNext();) { 834 q.remove(); 835 it.next(); 836 } 837 assertEquals(0, q.size()); 838 } 839 840 /** 841 * toString contains toStrings of elements 842 */ 843 public void testToString() { 844 ArrayBlockingQueue q = populatedQueue(SIZE); 845 String s = q.toString(); 846 for (int i = 0; i < SIZE; ++i) { 847 assertTrue(s.contains(String.valueOf(i))); 848 } 849 } 850 851 /** 852 * offer transfers elements across Executor tasks 853 */ 854 public void testOfferInExecutor() { 855 final ArrayBlockingQueue q = new ArrayBlockingQueue(2); 856 q.add(one); 857 q.add(two); 858 final CheckedBarrier threadsStarted = new CheckedBarrier(2); 859 final ExecutorService executor = Executors.newFixedThreadPool(2); 860 try (PoolCleaner cleaner = cleaner(executor)) { 861 executor.execute(new CheckedRunnable() { 862 public void realRun() throws InterruptedException { 863 assertFalse(q.offer(three)); 864 threadsStarted.await(); 865 assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS)); 866 assertEquals(0, q.remainingCapacity()); 867 }}); 868 869 executor.execute(new CheckedRunnable() { 870 public void realRun() throws InterruptedException { 871 threadsStarted.await(); 872 assertEquals(0, q.remainingCapacity()); 873 assertSame(one, q.take()); 874 }}); 875 } 876 } 877 878 /** 879 * timed poll retrieves elements across Executor threads 880 */ 881 public void testPollInExecutor() { 882 final ArrayBlockingQueue q = new ArrayBlockingQueue(2); 883 final CheckedBarrier threadsStarted = new CheckedBarrier(2); 884 final ExecutorService executor = Executors.newFixedThreadPool(2); 885 try (PoolCleaner cleaner = cleaner(executor)) { 886 executor.execute(new CheckedRunnable() { 887 public void realRun() throws InterruptedException { 888 assertNull(q.poll()); 889 threadsStarted.await(); 890 assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS)); 891 checkEmpty(q); 892 }}); 893 894 executor.execute(new CheckedRunnable() { 895 public void realRun() throws InterruptedException { 896 threadsStarted.await(); 897 q.put(one); 898 }}); 899 } 900 } 901 902 /** 903 * A deserialized/reserialized queue has same elements in same order 904 */ 905 public void testSerialization() throws Exception { 906 Queue x = populatedQueue(SIZE); 907 Queue y = serialClone(x); 908 909 assertNotSame(x, y); 910 assertEquals(x.size(), y.size()); 911 assertEquals(x.toString(), y.toString()); 912 assertTrue(Arrays.equals(x.toArray(), y.toArray())); 913 while (!x.isEmpty()) { 914 assertFalse(y.isEmpty()); 915 assertEquals(x.remove(), y.remove()); 916 } 917 assertTrue(y.isEmpty()); 918 } 919 920 /** 921 * drainTo(c) empties queue into another collection c 922 */ 923 public void testDrainTo() { 924 ArrayBlockingQueue q = populatedQueue(SIZE); 925 ArrayList l = new ArrayList(); 926 q.drainTo(l); 927 assertEquals(0, q.size()); 928 assertEquals(SIZE, l.size()); 929 for (int i = 0; i < SIZE; ++i) 930 assertEquals(l.get(i), new Integer(i)); 931 q.add(zero); 932 q.add(one); 933 assertFalse(q.isEmpty()); 934 assertTrue(q.contains(zero)); 935 assertTrue(q.contains(one)); 936 l.clear(); 937 q.drainTo(l); 938 assertEquals(0, q.size()); 939 assertEquals(2, l.size()); 940 for (int i = 0; i < 2; ++i) 941 assertEquals(l.get(i), new Integer(i)); 942 } 943 944 /** 945 * drainTo empties full queue, unblocking a waiting put. 946 */ 947 public void testDrainToWithActivePut() throws InterruptedException { 948 final ArrayBlockingQueue q = populatedQueue(SIZE); 949 Thread t = new Thread(new CheckedRunnable() { 950 public void realRun() throws InterruptedException { 951 q.put(new Integer(SIZE + 1)); 952 }}); 953 954 t.start(); 955 ArrayList l = new ArrayList(); 956 q.drainTo(l); 957 assertTrue(l.size() >= SIZE); 958 for (int i = 0; i < SIZE; ++i) 959 assertEquals(l.get(i), new Integer(i)); 960 t.join(); 961 assertTrue(q.size() + l.size() >= SIZE); 962 } 963 964 /** 965 * drainTo(c, n) empties first min(n, size) elements of queue into c 966 */ 967 public void testDrainToN() { 968 ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE * 2); 969 for (int i = 0; i < SIZE + 2; ++i) { 970 for (int j = 0; j < SIZE; j++) 971 assertTrue(q.offer(new Integer(j))); 972 ArrayList l = new ArrayList(); 973 q.drainTo(l, i); 974 int k = (i < SIZE) ? i : SIZE; 975 assertEquals(k, l.size()); 976 assertEquals(SIZE - k, q.size()); 977 for (int j = 0; j < k; ++j) 978 assertEquals(l.get(j), new Integer(j)); 979 do {} while (q.poll() != null); 980 } 981 } 982 983 /** 984 * remove(null), contains(null) always return false 985 */ 986 public void testNeverContainsNull() { 987 Collection<?>[] qs = { 988 populatedQueue(0, 1, 10, false), 989 populatedQueue(2, 2, 10, true), 990 }; 991 992 for (Collection<?> q : qs) { 993 assertFalse(q.contains(null)); 994 assertFalse(q.remove(null)); 995 } 996 } 997 }