ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SynchronousQueueTest.java
Revision: 1.58
Committed: Sun May 14 04:02:06 2017 UTC (7 years ago) by jsr166
Branch: MAIN
Changes since 1.57: +7 -0 lines
Log Message:
improve testPutWithTake

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 ISE 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 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 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 assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
200 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
201 pleaseInterrupt.countDown();
202 try {
203 q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
204 shouldThrow();
205 } catch (InterruptedException success) {}
206 assertFalse(Thread.interrupted());
207 }});
208
209 await(pleaseInterrupt);
210 assertThreadBlocks(t, Thread.State.TIMED_WAITING);
211 t.interrupt();
212 awaitTermination(t);
213 }
214
215 /**
216 * poll return null if no active putter
217 */
218 public void testPoll() { testPoll(false); }
219 public void testPoll_fair() { testPoll(true); }
220 public void testPoll(boolean fair) {
221 final SynchronousQueue q = new SynchronousQueue(fair);
222 assertNull(q.poll());
223 }
224
225 /**
226 * timed poll with zero timeout times out if no active putter
227 */
228 public void testTimedPoll0() { testTimedPoll0(false); }
229 public void testTimedPoll0_fair() { testTimedPoll0(true); }
230 public void testTimedPoll0(boolean fair) {
231 final SynchronousQueue q = new SynchronousQueue(fair);
232 try { assertNull(q.poll(0, MILLISECONDS)); }
233 catch (InterruptedException e) { threadUnexpectedException(e); }
234 }
235
236 /**
237 * timed poll with nonzero timeout times out if no active putter
238 */
239 public void testTimedPoll() {
240 final boolean fair = ThreadLocalRandom.current().nextBoolean();
241 final SynchronousQueue q = new SynchronousQueue(fair);
242 final long startTime = System.nanoTime();
243 try { assertNull(q.poll(timeoutMillis(), MILLISECONDS)); }
244 catch (InterruptedException e) { threadUnexpectedException(e); }
245 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
246 }
247
248 /**
249 * timed poll before a delayed offer times out, returning null;
250 * after offer succeeds; on interruption throws
251 */
252 public void testTimedPollWithOffer() {
253 final boolean fair = ThreadLocalRandom.current().nextBoolean();
254 final SynchronousQueue q = new SynchronousQueue(fair);
255 final CountDownLatch pleaseOffer = new CountDownLatch(1);
256 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
257 Thread t = newStartedThread(new CheckedRunnable() {
258 public void realRun() throws InterruptedException {
259 long startTime = System.nanoTime();
260 assertNull(q.poll(timeoutMillis(), MILLISECONDS));
261 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
262
263 pleaseOffer.countDown();
264 startTime = System.nanoTime();
265 assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
266
267 Thread.currentThread().interrupt();
268 try {
269 q.poll(LONG_DELAY_MS, MILLISECONDS);
270 shouldThrow();
271 } catch (InterruptedException success) {}
272 assertFalse(Thread.interrupted());
273
274 pleaseInterrupt.countDown();
275 try {
276 q.poll(LONG_DELAY_MS, MILLISECONDS);
277 shouldThrow();
278 } catch (InterruptedException success) {}
279 assertFalse(Thread.interrupted());
280
281 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
282 }});
283
284 await(pleaseOffer);
285 long startTime = System.nanoTime();
286 try { assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); }
287 catch (InterruptedException e) { threadUnexpectedException(e); }
288 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
289
290 await(pleaseInterrupt);
291 assertThreadBlocks(t, Thread.State.TIMED_WAITING);
292 t.interrupt();
293 awaitTermination(t);
294 }
295
296 /**
297 * peek() returns null if no active putter
298 */
299 public void testPeek() { testPeek(false); }
300 public void testPeek_fair() { testPeek(true); }
301 public void testPeek(boolean fair) {
302 final SynchronousQueue q = new SynchronousQueue(fair);
303 assertNull(q.peek());
304 }
305
306 /**
307 * element() throws NoSuchElementException if no active putter
308 */
309 public void testElement() { testElement(false); }
310 public void testElement_fair() { testElement(true); }
311 public void testElement(boolean fair) {
312 final SynchronousQueue q = new SynchronousQueue(fair);
313 try {
314 q.element();
315 shouldThrow();
316 } catch (NoSuchElementException success) {}
317 }
318
319 /**
320 * remove() throws NoSuchElementException if no active putter
321 */
322 public void testRemove() { testRemove(false); }
323 public void testRemove_fair() { testRemove(true); }
324 public void testRemove(boolean fair) {
325 final SynchronousQueue q = new SynchronousQueue(fair);
326 try {
327 q.remove();
328 shouldThrow();
329 } catch (NoSuchElementException success) {}
330 }
331
332 /**
333 * contains returns false
334 */
335 public void testContains() { testContains(false); }
336 public void testContains_fair() { testContains(true); }
337 public void testContains(boolean fair) {
338 final SynchronousQueue q = new SynchronousQueue(fair);
339 assertFalse(q.contains(zero));
340 }
341
342 /**
343 * clear ensures isEmpty
344 */
345 public void testClear() { testClear(false); }
346 public void testClear_fair() { testClear(true); }
347 public void testClear(boolean fair) {
348 final SynchronousQueue q = new SynchronousQueue(fair);
349 q.clear();
350 assertTrue(q.isEmpty());
351 }
352
353 /**
354 * containsAll returns false unless empty
355 */
356 public void testContainsAll() { testContainsAll(false); }
357 public void testContainsAll_fair() { testContainsAll(true); }
358 public void testContainsAll(boolean fair) {
359 final SynchronousQueue q = new SynchronousQueue(fair);
360 Integer[] empty = new Integer[0];
361 assertTrue(q.containsAll(Arrays.asList(empty)));
362 Integer[] ints = new Integer[1]; ints[0] = zero;
363 assertFalse(q.containsAll(Arrays.asList(ints)));
364 }
365
366 /**
367 * retainAll returns false
368 */
369 public void testRetainAll() { testRetainAll(false); }
370 public void testRetainAll_fair() { testRetainAll(true); }
371 public void testRetainAll(boolean fair) {
372 final SynchronousQueue q = new SynchronousQueue(fair);
373 Integer[] empty = new Integer[0];
374 assertFalse(q.retainAll(Arrays.asList(empty)));
375 Integer[] ints = new Integer[1]; ints[0] = zero;
376 assertFalse(q.retainAll(Arrays.asList(ints)));
377 }
378
379 /**
380 * removeAll returns false
381 */
382 public void testRemoveAll() { testRemoveAll(false); }
383 public void testRemoveAll_fair() { testRemoveAll(true); }
384 public void testRemoveAll(boolean fair) {
385 final SynchronousQueue q = new SynchronousQueue(fair);
386 Integer[] empty = new Integer[0];
387 assertFalse(q.removeAll(Arrays.asList(empty)));
388 Integer[] ints = new Integer[1]; ints[0] = zero;
389 assertFalse(q.containsAll(Arrays.asList(ints)));
390 }
391
392 /**
393 * toArray is empty
394 */
395 public void testToArray() { testToArray(false); }
396 public void testToArray_fair() { testToArray(true); }
397 public void testToArray(boolean fair) {
398 final SynchronousQueue q = new SynchronousQueue(fair);
399 Object[] o = q.toArray();
400 assertEquals(0, o.length);
401 }
402
403 /**
404 * toArray(Integer array) returns its argument with the first
405 * element (if present) nulled out
406 */
407 public void testToArray2() { testToArray2(false); }
408 public void testToArray2_fair() { testToArray2(true); }
409 public void testToArray2(boolean fair) {
410 final SynchronousQueue<Integer> q = new SynchronousQueue<>(fair);
411 Integer[] a;
412
413 a = new Integer[0];
414 assertSame(a, q.toArray(a));
415
416 a = new Integer[3];
417 Arrays.fill(a, 42);
418 assertSame(a, q.toArray(a));
419 assertNull(a[0]);
420 for (int i = 1; i < a.length; i++)
421 assertEquals(42, (int) a[i]);
422 }
423
424 /**
425 * toArray(null) throws NPE
426 */
427 public void testToArray_null() { testToArray_null(false); }
428 public void testToArray_null_fair() { testToArray_null(true); }
429 public void testToArray_null(boolean fair) {
430 final SynchronousQueue q = new SynchronousQueue(fair);
431 try {
432 Object[] o = q.toArray(null);
433 shouldThrow();
434 } catch (NullPointerException success) {}
435 }
436
437 /**
438 * iterator does not traverse any elements
439 */
440 public void testIterator() { testIterator(false); }
441 public void testIterator_fair() { testIterator(true); }
442 public void testIterator(boolean fair) {
443 assertIteratorExhausted(new SynchronousQueue(fair).iterator());
444 }
445
446 /**
447 * iterator remove throws ISE
448 */
449 public void testIteratorRemove() { testIteratorRemove(false); }
450 public void testIteratorRemove_fair() { testIteratorRemove(true); }
451 public void testIteratorRemove(boolean fair) {
452 final SynchronousQueue q = new SynchronousQueue(fair);
453 Iterator it = q.iterator();
454 try {
455 it.remove();
456 shouldThrow();
457 } catch (IllegalStateException success) {}
458 }
459
460 /**
461 * toString returns a non-null string
462 */
463 public void testToString() { testToString(false); }
464 public void testToString_fair() { testToString(true); }
465 public void testToString(boolean fair) {
466 final SynchronousQueue q = new SynchronousQueue(fair);
467 String s = q.toString();
468 assertNotNull(s);
469 }
470
471 /**
472 * offer transfers elements across Executor tasks
473 */
474 public void testOfferInExecutor() { testOfferInExecutor(false); }
475 public void testOfferInExecutor_fair() { testOfferInExecutor(true); }
476 public void testOfferInExecutor(boolean fair) {
477 final SynchronousQueue q = new SynchronousQueue(fair);
478 final CheckedBarrier threadsStarted = new CheckedBarrier(2);
479 final ExecutorService executor = Executors.newFixedThreadPool(2);
480 try (PoolCleaner cleaner = cleaner(executor)) {
481
482 executor.execute(new CheckedRunnable() {
483 public void realRun() throws InterruptedException {
484 assertFalse(q.offer(one));
485 threadsStarted.await();
486 assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
487 assertEquals(0, q.remainingCapacity());
488 }});
489
490 executor.execute(new CheckedRunnable() {
491 public void realRun() throws InterruptedException {
492 threadsStarted.await();
493 assertSame(one, q.take());
494 }});
495 }
496 }
497
498 /**
499 * timed poll retrieves elements across Executor threads
500 */
501 public void testPollInExecutor() { testPollInExecutor(false); }
502 public void testPollInExecutor_fair() { testPollInExecutor(true); }
503 public void testPollInExecutor(boolean fair) {
504 final SynchronousQueue q = new SynchronousQueue(fair);
505 final CheckedBarrier threadsStarted = new CheckedBarrier(2);
506 final ExecutorService executor = Executors.newFixedThreadPool(2);
507 try (PoolCleaner cleaner = cleaner(executor)) {
508 executor.execute(new CheckedRunnable() {
509 public void realRun() throws InterruptedException {
510 assertNull(q.poll());
511 threadsStarted.await();
512 assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
513 assertTrue(q.isEmpty());
514 }});
515
516 executor.execute(new CheckedRunnable() {
517 public void realRun() throws InterruptedException {
518 threadsStarted.await();
519 q.put(one);
520 }});
521 }
522 }
523
524 /**
525 * a deserialized serialized queue is usable
526 */
527 public void testSerialization() {
528 final SynchronousQueue x = new SynchronousQueue();
529 final SynchronousQueue y = new SynchronousQueue(false);
530 final SynchronousQueue z = new SynchronousQueue(true);
531 assertSerialEquals(x, y);
532 assertNotSerialEquals(x, z);
533 SynchronousQueue[] qs = { x, y, z };
534 for (SynchronousQueue q : qs) {
535 SynchronousQueue clone = serialClone(q);
536 assertNotSame(q, clone);
537 assertSerialEquals(q, clone);
538 assertTrue(clone.isEmpty());
539 assertEquals(0, clone.size());
540 assertEquals(0, clone.remainingCapacity());
541 assertFalse(clone.offer(zero));
542 }
543 }
544
545 /**
546 * drainTo(c) of empty queue doesn't transfer elements
547 */
548 public void testDrainTo() { testDrainTo(false); }
549 public void testDrainTo_fair() { testDrainTo(true); }
550 public void testDrainTo(boolean fair) {
551 final SynchronousQueue q = new SynchronousQueue(fair);
552 ArrayList l = new ArrayList();
553 q.drainTo(l);
554 assertEquals(0, q.size());
555 assertEquals(0, l.size());
556 }
557
558 /**
559 * drainTo empties queue, unblocking a waiting put.
560 */
561 public void testDrainToWithActivePut() { testDrainToWithActivePut(false); }
562 public void testDrainToWithActivePut_fair() { testDrainToWithActivePut(true); }
563 public void testDrainToWithActivePut(boolean fair) {
564 final SynchronousQueue q = new SynchronousQueue(fair);
565 Thread t = newStartedThread(new CheckedRunnable() {
566 public void realRun() throws InterruptedException {
567 q.put(one);
568 }});
569
570 ArrayList l = new ArrayList();
571 long startTime = System.nanoTime();
572 while (l.isEmpty()) {
573 q.drainTo(l);
574 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
575 fail("timed out");
576 Thread.yield();
577 }
578 assertEquals(1, l.size());
579 assertSame(one, l.get(0));
580 awaitTermination(t);
581 }
582
583 /**
584 * drainTo(c, n) empties up to n elements of queue into c
585 */
586 public void testDrainToN() throws InterruptedException {
587 final SynchronousQueue q = new SynchronousQueue();
588 Thread t1 = newStartedThread(new CheckedRunnable() {
589 public void realRun() throws InterruptedException {
590 q.put(one);
591 }});
592
593 Thread t2 = newStartedThread(new CheckedRunnable() {
594 public void realRun() throws InterruptedException {
595 q.put(two);
596 }});
597
598 ArrayList l = new ArrayList();
599 int drained;
600 while ((drained = q.drainTo(l, 1)) == 0) Thread.yield();
601 assertEquals(1, drained);
602 assertEquals(1, l.size());
603 while ((drained = q.drainTo(l, 1)) == 0) Thread.yield();
604 assertEquals(1, drained);
605 assertEquals(2, l.size());
606 assertTrue(l.contains(one));
607 assertTrue(l.contains(two));
608 awaitTermination(t1);
609 awaitTermination(t2);
610 }
611
612 /**
613 * remove(null), contains(null) always return false
614 */
615 public void testNeverContainsNull() {
616 Collection<?> q = new SynchronousQueue();
617 assertFalse(q.contains(null));
618 assertFalse(q.remove(null));
619 }
620
621 }