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 package jsr166; 10 11 import junit.framework.*; 12 import java.util.*; 13 import java.util.concurrent.CountDownLatch; 14 import java.util.concurrent.Exchanger; 15 import java.util.concurrent.TimeoutException; 16 import static java.util.concurrent.TimeUnit.MILLISECONDS; 17 18 public class ExchangerTest extends JSR166TestCase { 19 20 /** 21 * exchange exchanges objects across two threads 22 */ testExchange()23 public void testExchange() { 24 final Exchanger e = new Exchanger(); 25 Thread t1 = newStartedThread(new CheckedRunnable() { 26 public void realRun() throws InterruptedException { 27 assertSame(one, e.exchange(two)); 28 assertSame(two, e.exchange(one)); 29 }}); 30 Thread t2 = newStartedThread(new CheckedRunnable() { 31 public void realRun() throws InterruptedException { 32 assertSame(two, e.exchange(one)); 33 assertSame(one, e.exchange(two)); 34 }}); 35 36 awaitTermination(t1); 37 awaitTermination(t2); 38 } 39 40 /** 41 * timed exchange exchanges objects across two threads 42 */ testTimedExchange()43 public void testTimedExchange() { 44 final Exchanger e = new Exchanger(); 45 Thread t1 = newStartedThread(new CheckedRunnable() { 46 public void realRun() throws Exception { 47 assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS)); 48 assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS)); 49 }}); 50 Thread t2 = newStartedThread(new CheckedRunnable() { 51 public void realRun() throws Exception { 52 assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS)); 53 assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS)); 54 }}); 55 56 awaitTermination(t1); 57 awaitTermination(t2); 58 } 59 60 /** 61 * interrupt during wait for exchange throws IE 62 */ testExchange_InterruptedException()63 public void testExchange_InterruptedException() { 64 final Exchanger e = new Exchanger(); 65 final CountDownLatch threadStarted = new CountDownLatch(1); 66 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 67 public void realRun() throws InterruptedException { 68 threadStarted.countDown(); 69 e.exchange(one); 70 }}); 71 72 await(threadStarted); 73 t.interrupt(); 74 awaitTermination(t); 75 } 76 77 /** 78 * interrupt during wait for timed exchange throws IE 79 */ testTimedExchange_InterruptedException()80 public void testTimedExchange_InterruptedException() { 81 final Exchanger e = new Exchanger(); 82 final CountDownLatch threadStarted = new CountDownLatch(1); 83 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 84 public void realRun() throws Exception { 85 threadStarted.countDown(); 86 e.exchange(null, LONG_DELAY_MS, MILLISECONDS); 87 }}); 88 89 await(threadStarted); 90 t.interrupt(); 91 awaitTermination(t); 92 } 93 94 /** 95 * timeout during wait for timed exchange throws TimeoutException 96 */ testExchange_TimeoutException()97 public void testExchange_TimeoutException() { 98 final Exchanger e = new Exchanger(); 99 Thread t = newStartedThread(new CheckedRunnable() { 100 public void realRun() throws Exception { 101 long startTime = System.nanoTime(); 102 try { 103 e.exchange(null, timeoutMillis(), MILLISECONDS); 104 shouldThrow(); 105 } catch (TimeoutException success) {} 106 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 107 }}); 108 109 awaitTermination(t); 110 } 111 112 /** 113 * If one exchanging thread is interrupted, another succeeds. 114 */ testReplacementAfterExchange()115 public void testReplacementAfterExchange() { 116 final Exchanger e = new Exchanger(); 117 final CountDownLatch exchanged = new CountDownLatch(2); 118 final CountDownLatch interrupted = new CountDownLatch(1); 119 Thread t1 = newStartedThread(new CheckedInterruptedRunnable() { 120 public void realRun() throws InterruptedException { 121 assertSame(two, e.exchange(one)); 122 exchanged.countDown(); 123 e.exchange(two); 124 }}); 125 Thread t2 = newStartedThread(new CheckedRunnable() { 126 public void realRun() throws InterruptedException { 127 assertSame(one, e.exchange(two)); 128 exchanged.countDown(); 129 interrupted.await(); 130 assertSame(three, e.exchange(one)); 131 }}); 132 Thread t3 = newStartedThread(new CheckedRunnable() { 133 public void realRun() throws InterruptedException { 134 interrupted.await(); 135 assertSame(one, e.exchange(three)); 136 }}); 137 138 await(exchanged); 139 t1.interrupt(); 140 awaitTermination(t1); 141 interrupted.countDown(); 142 awaitTermination(t2); 143 awaitTermination(t3); 144 } 145 146 } 147