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