ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SynchronousQueueTest.java
Revision: 1.63
Committed: Sun Aug 11 22:29:27 2019 UTC (4 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.62: +10 -7 lines
Log Message:
more assertions; more interleavings

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 static java.util.concurrent.TimeUnit.MILLISECONDS;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collection;
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.Executors;
19 import java.util.concurrent.ExecutorService;
20 import java.util.concurrent.SynchronousQueue;
21 import java.util.concurrent.ThreadLocalRandom;
22
23 import junit.framework.Test;
24
25 public class SynchronousQueueTest extends JSR166TestCase {
26
27 public static class Fair extends BlockingQueueTest {
28 protected BlockingQueue emptyCollection() {
29 return new SynchronousQueue(true);
30 }
31 }
32
33 public static class NonFair extends BlockingQueueTest {
34 protected BlockingQueue emptyCollection() {
35 return new SynchronousQueue(false);
36 }
37 }
38
39 public static void main(String[] args) {
40 main(suite(), args);
41 }
42
43 public static Test suite() {
44 return newTestSuite(SynchronousQueueTest.class,
45 new Fair().testSuite(),
46 new NonFair().testSuite());
47 }
48
49 /**
50 * Any SynchronousQueue is both empty and full
51 */
52 public void testEmptyFull() { testEmptyFull(false); }
53 public void testEmptyFull_fair() { testEmptyFull(true); }
54 public void testEmptyFull(boolean fair) {
55 final SynchronousQueue q = new SynchronousQueue(fair);
56 assertTrue(q.isEmpty());
57 assertEquals(0, q.size());
58 assertEquals(0, q.remainingCapacity());
59 assertFalse(q.offer(zero));
60 }
61
62 /**
63 * offer fails if no active taker
64 */
65 public void testOffer() { testOffer(false); }
66 public void testOffer_fair() { testOffer(true); }
67 public void testOffer(boolean fair) {
68 SynchronousQueue q = new SynchronousQueue(fair);
69 assertFalse(q.offer(one));
70 }
71
72 /**
73 * add throws IllegalStateException if no active taker
74 */
75 public void testAdd() { testAdd(false); }
76 public void testAdd_fair() { testAdd(true); }
77 public void testAdd(boolean fair) {
78 SynchronousQueue q = new SynchronousQueue(fair);
79 assertEquals(0, q.remainingCapacity());
80 try {
81 q.add(one);
82 shouldThrow();
83 } catch (IllegalStateException success) {}
84 }
85
86 /**
87 * addAll(this) throws IllegalArgumentException
88 */
89 public void testAddAll_self() { testAddAll_self(false); }
90 public void testAddAll_self_fair() { testAddAll_self(true); }
91 public void testAddAll_self(boolean fair) {
92 SynchronousQueue q = new SynchronousQueue(fair);
93 try {
94 q.addAll(q);
95 shouldThrow();
96 } catch (IllegalArgumentException success) {}
97 }
98
99 /**
100 * addAll throws IllegalStateException if no active taker
101 */
102 public void testAddAll_ISE() { testAddAll_ISE(false); }
103 public void testAddAll_ISE_fair() { testAddAll_ISE(true); }
104 public void testAddAll_ISE(boolean fair) {
105 SynchronousQueue q = new SynchronousQueue(fair);
106 Integer[] ints = new Integer[1];
107 for (int i = 0; i < ints.length; i++)
108 ints[i] = i;
109 Collection<Integer> coll = Arrays.asList(ints);
110 try {
111 q.addAll(coll);
112 shouldThrow();
113 } catch (IllegalStateException success) {}
114 }
115
116 /**
117 * put blocks interruptibly if no active taker
118 */
119 public void testBlockingPut() { testBlockingPut(false); }
120 public void testBlockingPut_fair() { testBlockingPut(true); }
121 public void testBlockingPut(boolean fair) {
122 final SynchronousQueue q = new SynchronousQueue(fair);
123 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
124 Thread t = newStartedThread(new CheckedRunnable() {
125 public void realRun() throws InterruptedException {
126 Thread.currentThread().interrupt();
127 try {
128 q.put(99);
129 shouldThrow();
130 } catch (InterruptedException success) {}
131 assertFalse(Thread.interrupted());
132
133 pleaseInterrupt.countDown();
134 try {
135 q.put(99);
136 shouldThrow();
137 } catch (InterruptedException success) {}
138 assertFalse(Thread.interrupted());
139 }});
140
141 await(pleaseInterrupt);
142 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING);
143 t.interrupt();
144 awaitTermination(t);
145 assertEquals(0, q.remainingCapacity());
146 }
147
148 /**
149 * put blocks interruptibly waiting for take
150 */
151 public void testPutWithTake() { testPutWithTake(false); }
152 public void testPutWithTake_fair() { testPutWithTake(true); }
153 public void testPutWithTake(boolean fair) {
154 final SynchronousQueue q = new SynchronousQueue(fair);
155 final CountDownLatch pleaseTake = new CountDownLatch(1);
156 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
157 Thread t = newStartedThread(new CheckedRunnable() {
158 public void realRun() throws InterruptedException {
159 pleaseTake.countDown();
160 q.put(one);
161
162 Thread.currentThread().interrupt();
163 try {
164 q.put(99);
165 shouldThrow();
166 } catch (InterruptedException success) {}
167 assertFalse(Thread.interrupted());
168
169 pleaseInterrupt.countDown();
170 try {
171 q.put(99);
172 shouldThrow();
173 } catch (InterruptedException success) {}
174 assertFalse(Thread.interrupted());
175 }});
176
177 await(pleaseTake);
178 assertEquals(0, q.remainingCapacity());
179 try { assertSame(one, q.take()); }
180 catch (InterruptedException e) { threadUnexpectedException(e); }
181
182 await(pleaseInterrupt);
183 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING);
184 t.interrupt();
185 awaitTermination(t);
186 assertEquals(0, q.remainingCapacity());
187 }
188
189 /**
190 * timed offer times out if elements not taken
191 */
192 public void testTimedOffer() {
193 final boolean fair = ThreadLocalRandom.current().nextBoolean();
194 final SynchronousQueue q = new SynchronousQueue(fair);
195 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
196 Thread t = newStartedThread(new CheckedRunnable() {
197 public void realRun() throws InterruptedException {
198 long startTime = System.nanoTime();
199
200 assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
201 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
202
203 Thread.currentThread().interrupt();
204 try {
205 q.offer(new Object(), randomTimeout(), randomTimeUnit());
206 shouldThrow();
207 } catch (InterruptedException success) {}
208 assertFalse(Thread.interrupted());
209
210 pleaseInterrupt.countDown();
211 try {
212 q.offer(new Object(), LONG_DELAY_MS, MILLISECONDS);
213 shouldThrow();
214 } catch (InterruptedException success) {}
215 assertFalse(Thread.interrupted());
216
217 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
218 }});
219
220 await(pleaseInterrupt);
221 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
222 t.interrupt();
223 awaitTermination(t);
224 }
225
226 /**
227 * poll return null if no active putter
228 */
229 public void testPoll() { testPoll(false); }
230 public void testPoll_fair() { testPoll(true); }
231 public void testPoll(boolean fair) {
232 final SynchronousQueue q = new SynchronousQueue(fair);
233 assertNull(q.poll());
234 }
235
236 /**
237 * timed poll with zero timeout times out if no active putter
238 */
239 public void testTimedPoll0() { testTimedPoll0(false); }
240 public void testTimedPoll0_fair() { testTimedPoll0(true); }
241 public void testTimedPoll0(boolean fair) {
242 final SynchronousQueue q = new SynchronousQueue(fair);
243 try { assertNull(q.poll(0, MILLISECONDS)); }
244 catch (InterruptedException e) { threadUnexpectedException(e); }
245 }
246
247 /**
248 * timed poll with nonzero timeout times out if no active putter
249 */
250 public void testTimedPoll() {
251 final boolean fair = ThreadLocalRandom.current().nextBoolean();
252 final SynchronousQueue q = new SynchronousQueue(fair);
253 final long startTime = System.nanoTime();
254 try { assertNull(q.poll(timeoutMillis(), MILLISECONDS)); }
255 catch (InterruptedException e) { threadUnexpectedException(e); }
256 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
257 }
258
259 /**
260 * timed poll before a delayed offer times out, returning null;
261 * after offer succeeds; on interruption throws
262 */
263 public void testTimedPollWithOffer() {
264 final boolean fair = ThreadLocalRandom.current().nextBoolean();
265 final SynchronousQueue q = new SynchronousQueue(fair);
266 final CountDownLatch pleaseOffer = new CountDownLatch(1);
267 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
268 Thread t = newStartedThread(new CheckedRunnable() {
269 public void realRun() throws InterruptedException {
270 long startTime = System.nanoTime();
271 assertNull(q.poll(timeoutMillis(), MILLISECONDS));
272 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
273
274 pleaseOffer.countDown();
275 startTime = System.nanoTime();
276 assertSame(zero, 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(LONG_DELAY_MS, MILLISECONDS);
288 shouldThrow();
289 } catch (InterruptedException success) {}
290 assertFalse(Thread.interrupted());
291
292 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
293 }});
294
295 await(pleaseOffer);
296 long startTime = System.nanoTime();
297 try { assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); }
298 catch (InterruptedException e) { threadUnexpectedException(e); }
299 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
300
301 await(pleaseInterrupt);
302 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
303 t.interrupt();
304 awaitTermination(t);
305 }
306
307 /**
308 * peek() returns null if no active putter
309 */
310 public void testPeek() { testPeek(false); }
311 public void testPeek_fair() { testPeek(true); }
312 public void testPeek(boolean fair) {
313 final SynchronousQueue q = new SynchronousQueue(fair);
314 assertNull(q.peek());
315 }
316
317 /**
318 * element() throws NoSuchElementException if no active putter
319 */
320 public void testElement() { testElement(false); }
321 public void testElement_fair() { testElement(true); }
322 public void testElement(boolean fair) {
323 final SynchronousQueue q = new SynchronousQueue(fair);
324 try {
325 q.element();
326 shouldThrow();
327 } catch (NoSuchElementException success) {}
328 }
329
330 /**
331 * remove() throws NoSuchElementException if no active putter
332 */
333 public void testRemove() { testRemove(false); }
334 public void testRemove_fair() { testRemove(true); }
335 public void testRemove(boolean fair) {
336 final SynchronousQueue q = new SynchronousQueue(fair);
337 try {
338 q.remove();
339 shouldThrow();
340 } catch (NoSuchElementException success) {}
341 }
342
343 /**
344 * contains returns false
345 */
346 public void testContains() { testContains(false); }
347 public void testContains_fair() { testContains(true); }
348 public void testContains(boolean fair) {
349 final SynchronousQueue q = new SynchronousQueue(fair);
350 assertFalse(q.contains(zero));
351 }
352
353 /**
354 * clear ensures isEmpty
355 */
356 public void testClear() { testClear(false); }
357 public void testClear_fair() { testClear(true); }
358 public void testClear(boolean fair) {
359 final SynchronousQueue q = new SynchronousQueue(fair);
360 q.clear();
361 assertTrue(q.isEmpty());
362 }
363
364 /**
365 * containsAll returns false unless empty
366 */
367 public void testContainsAll() { testContainsAll(false); }
368 public void testContainsAll_fair() { testContainsAll(true); }
369 public void testContainsAll(boolean fair) {
370 final SynchronousQueue q = new SynchronousQueue(fair);
371 Integer[] empty = new Integer[0];
372 assertTrue(q.containsAll(Arrays.asList(empty)));
373 Integer[] ints = new Integer[1]; ints[0] = zero;
374 assertFalse(q.containsAll(Arrays.asList(ints)));
375 }
376
377 /**
378 * retainAll returns false
379 */
380 public void testRetainAll() { testRetainAll(false); }
381 public void testRetainAll_fair() { testRetainAll(true); }
382 public void testRetainAll(boolean fair) {
383 final SynchronousQueue q = new SynchronousQueue(fair);
384 Integer[] empty = new Integer[0];
385 assertFalse(q.retainAll(Arrays.asList(empty)));
386 Integer[] ints = new Integer[1]; ints[0] = zero;
387 assertFalse(q.retainAll(Arrays.asList(ints)));
388 }
389
390 /**
391 * removeAll returns false
392 */
393 public void testRemoveAll() { testRemoveAll(false); }
394 public void testRemoveAll_fair() { testRemoveAll(true); }
395 public void testRemoveAll(boolean fair) {
396 final SynchronousQueue q = new SynchronousQueue(fair);
397 Integer[] empty = new Integer[0];
398 assertFalse(q.removeAll(Arrays.asList(empty)));
399 Integer[] ints = new Integer[1]; ints[0] = zero;
400 assertFalse(q.containsAll(Arrays.asList(ints)));
401 }
402
403 /**
404 * toArray is empty
405 */
406 public void testToArray() { testToArray(false); }
407 public void testToArray_fair() { testToArray(true); }
408 public void testToArray(boolean fair) {
409 final SynchronousQueue q = new SynchronousQueue(fair);
410 Object[] o = q.toArray();
411 assertEquals(0, o.length);
412 }
413
414 /**
415 * toArray(Integer array) returns its argument with the first
416 * element (if present) nulled out
417 */
418 public void testToArray2() { testToArray2(false); }
419 public void testToArray2_fair() { testToArray2(true); }
420 public void testToArray2(boolean fair) {
421 final SynchronousQueue<Integer> q = new SynchronousQueue<>(fair);
422 Integer[] a;
423
424 a = new Integer[0];
425 assertSame(a, q.toArray(a));
426
427 a = new Integer[3];
428 Arrays.fill(a, 42);
429 assertSame(a, q.toArray(a));
430 assertNull(a[0]);
431 for (int i = 1; i < a.length; i++)
432 assertEquals(42, (int) a[i]);
433 }
434
435 /**
436 * toArray(null) throws NPE
437 */
438 public void testToArray_null() { testToArray_null(false); }
439 public void testToArray_null_fair() { testToArray_null(true); }
440 public void testToArray_null(boolean fair) {
441 final SynchronousQueue q = new SynchronousQueue(fair);
442 try {
443 Object[] o = q.toArray((Object[])null);
444 shouldThrow();
445 } catch (NullPointerException success) {}
446 }
447
448 /**
449 * iterator does not traverse any elements
450 */
451 public void testIterator() { testIterator(false); }
452 public void testIterator_fair() { testIterator(true); }
453 public void testIterator(boolean fair) {
454 assertIteratorExhausted(new SynchronousQueue(fair).iterator());
455 }
456
457 /**
458 * iterator remove throws IllegalStateException
459 */
460 public void testIteratorRemove() { testIteratorRemove(false); }
461 public void testIteratorRemove_fair() { testIteratorRemove(true); }
462 public void testIteratorRemove(boolean fair) {
463 final SynchronousQueue q = new SynchronousQueue(fair);
464 Iterator it = q.iterator();
465 try {
466 it.remove();
467 shouldThrow();
468 } catch (IllegalStateException success) {}
469 }
470
471 /**
472 * toString returns a non-null string
473 */
474 public void testToString() { testToString(false); }
475 public void testToString_fair() { testToString(true); }
476 public void testToString(boolean fair) {
477 final SynchronousQueue q = new SynchronousQueue(fair);
478 String s = q.toString();
479 assertNotNull(s);
480 }
481
482 /**
483 * offer transfers elements across Executor tasks
484 */
485 public void testOfferInExecutor() { testOfferInExecutor(false); }
486 public void testOfferInExecutor_fair() { testOfferInExecutor(true); }
487 public void testOfferInExecutor(boolean fair) {
488 final SynchronousQueue q = new SynchronousQueue(fair);
489 final CheckedBarrier threadsStarted = new CheckedBarrier(2);
490 final ExecutorService executor = Executors.newFixedThreadPool(2);
491 try (PoolCleaner cleaner = cleaner(executor)) {
492
493 executor.execute(new CheckedRunnable() {
494 public void realRun() throws InterruptedException {
495 assertFalse(q.offer(one));
496 threadsStarted.await();
497 assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
498 assertEquals(0, q.remainingCapacity());
499 }});
500
501 executor.execute(new CheckedRunnable() {
502 public void realRun() throws InterruptedException {
503 threadsStarted.await();
504 assertSame(one, q.take());
505 }});
506 }
507 }
508
509 /**
510 * timed poll retrieves elements across Executor threads
511 */
512 public void testPollInExecutor() { testPollInExecutor(false); }
513 public void testPollInExecutor_fair() { testPollInExecutor(true); }
514 public void testPollInExecutor(boolean fair) {
515 final SynchronousQueue q = new SynchronousQueue(fair);
516 final CheckedBarrier threadsStarted = new CheckedBarrier(2);
517 final ExecutorService executor = Executors.newFixedThreadPool(2);
518 try (PoolCleaner cleaner = cleaner(executor)) {
519 executor.execute(new CheckedRunnable() {
520 public void realRun() throws InterruptedException {
521 assertNull(q.poll());
522 threadsStarted.await();
523 assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
524 assertTrue(q.isEmpty());
525 }});
526
527 executor.execute(new CheckedRunnable() {
528 public void realRun() throws InterruptedException {
529 threadsStarted.await();
530 q.put(one);
531 }});
532 }
533 }
534
535 /**
536 * a deserialized/reserialized queue is usable
537 */
538 public void testSerialization() {
539 final SynchronousQueue x = new SynchronousQueue();
540 final SynchronousQueue y = new SynchronousQueue(false);
541 final SynchronousQueue z = new SynchronousQueue(true);
542 assertSerialEquals(x, y);
543 assertNotSerialEquals(x, z);
544 SynchronousQueue[] qs = { x, y, z };
545 for (SynchronousQueue q : qs) {
546 SynchronousQueue clone = serialClone(q);
547 assertNotSame(q, clone);
548 assertSerialEquals(q, clone);
549 assertTrue(clone.isEmpty());
550 assertEquals(0, clone.size());
551 assertEquals(0, clone.remainingCapacity());
552 assertFalse(clone.offer(zero));
553 }
554 }
555
556 /**
557 * drainTo(c) of empty queue doesn't transfer elements
558 */
559 public void testDrainTo() { testDrainTo(false); }
560 public void testDrainTo_fair() { testDrainTo(true); }
561 public void testDrainTo(boolean fair) {
562 final SynchronousQueue q = new SynchronousQueue(fair);
563 ArrayList l = new ArrayList();
564 q.drainTo(l);
565 assertEquals(0, q.size());
566 assertEquals(0, l.size());
567 }
568
569 /**
570 * drainTo empties queue, unblocking a waiting put.
571 */
572 public void testDrainToWithActivePut() { testDrainToWithActivePut(false); }
573 public void testDrainToWithActivePut_fair() { testDrainToWithActivePut(true); }
574 public void testDrainToWithActivePut(boolean fair) {
575 final SynchronousQueue q = new SynchronousQueue(fair);
576 Thread t = newStartedThread(new CheckedRunnable() {
577 public void realRun() throws InterruptedException {
578 q.put(one);
579 }});
580
581 ArrayList l = new ArrayList();
582 long startTime = System.nanoTime();
583 while (l.isEmpty()) {
584 q.drainTo(l);
585 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
586 fail("timed out");
587 Thread.yield();
588 }
589 assertEquals(1, l.size());
590 assertSame(one, l.get(0));
591 awaitTermination(t);
592 }
593
594 /**
595 * drainTo(c, n) empties up to n elements of queue into c
596 */
597 public void testDrainToN() throws InterruptedException {
598 final SynchronousQueue q = new SynchronousQueue();
599 Thread t1 = newStartedThread(new CheckedRunnable() {
600 public void realRun() throws InterruptedException {
601 q.put(one);
602 }});
603
604 Thread t2 = newStartedThread(new CheckedRunnable() {
605 public void realRun() throws InterruptedException {
606 q.put(two);
607 }});
608
609 ArrayList l = new ArrayList();
610 int drained;
611 while ((drained = q.drainTo(l, 1)) == 0) Thread.yield();
612 assertEquals(1, drained);
613 assertEquals(1, l.size());
614 while ((drained = q.drainTo(l, 1)) == 0) Thread.yield();
615 assertEquals(1, drained);
616 assertEquals(2, l.size());
617 assertTrue(l.contains(one));
618 assertTrue(l.contains(two));
619 awaitTermination(t1);
620 awaitTermination(t2);
621 }
622
623 /**
624 * remove(null), contains(null) always return false
625 */
626 public void testNeverContainsNull() {
627 Collection<?> q = new SynchronousQueue();
628 assertFalse(q.contains(null));
629 assertFalse(q.remove(null));
630 }
631
632 }