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.concurrent.CountDownLatch; 39 import java.util.concurrent.Exchanger; 40 import java.util.concurrent.TimeoutException; 41 42 import junit.framework.Test; 43 import junit.framework.TestSuite; 44 45 public class ExchangerTest extends JSR166TestCase { 46 main(String[] args)47 public static void main(String[] args) { 48 main(suite(), args); 49 } suite()50 public static Test suite() { 51 return new TestSuite(ExchangerTest.class); 52 } 53 54 /** 55 * exchange exchanges objects across two threads 56 */ testExchange()57 public void testExchange() { 58 final Exchanger<Item> e = new Exchanger<>(); 59 Thread t1 = newStartedThread(new CheckedRunnable() { 60 public void realRun() throws InterruptedException { 61 assertSame(one, e.exchange(two)); 62 assertSame(two, e.exchange(one)); 63 }}); 64 Thread t2 = newStartedThread(new CheckedRunnable() { 65 public void realRun() throws InterruptedException { 66 assertSame(two, e.exchange(one)); 67 assertSame(one, e.exchange(two)); 68 }}); 69 70 awaitTermination(t1); 71 awaitTermination(t2); 72 } 73 74 /** 75 * timed exchange exchanges objects across two threads 76 */ testTimedExchange()77 public void testTimedExchange() { 78 final Exchanger<Item> e = new Exchanger<>(); 79 Thread t1 = newStartedThread(new CheckedRunnable() { 80 public void realRun() throws Exception { 81 assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS)); 82 assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS)); 83 }}); 84 Thread t2 = newStartedThread(new CheckedRunnable() { 85 public void realRun() throws Exception { 86 assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS)); 87 assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS)); 88 }}); 89 90 awaitTermination(t1); 91 awaitTermination(t2); 92 } 93 94 /** 95 * interrupt during wait for exchange throws InterruptedException 96 */ testExchange_InterruptedException()97 public void testExchange_InterruptedException() { 98 final Exchanger<Item> e = new Exchanger<>(); 99 final CountDownLatch threadStarted = new CountDownLatch(1); 100 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 101 public void realRun() throws InterruptedException { 102 threadStarted.countDown(); 103 e.exchange(one); 104 }}); 105 106 await(threadStarted); 107 t.interrupt(); 108 awaitTermination(t); 109 } 110 111 /** 112 * interrupt during wait for timed exchange throws InterruptedException 113 */ testTimedExchange_InterruptedException()114 public void testTimedExchange_InterruptedException() { 115 final Exchanger<Item> e = new Exchanger<>(); 116 final CountDownLatch threadStarted = new CountDownLatch(1); 117 Thread t = newStartedThread(new CheckedInterruptedRunnable() { 118 public void realRun() throws Exception { 119 threadStarted.countDown(); 120 e.exchange(null, LONG_DELAY_MS, MILLISECONDS); 121 }}); 122 123 await(threadStarted); 124 t.interrupt(); 125 awaitTermination(t); 126 } 127 128 /** 129 * timeout during wait for timed exchange throws TimeoutException 130 */ testExchange_TimeoutException()131 public void testExchange_TimeoutException() { 132 final Exchanger<Item> e = new Exchanger<>(); 133 Thread t = newStartedThread(new CheckedRunnable() { 134 public void realRun() throws Exception { 135 long startTime = System.nanoTime(); 136 try { 137 e.exchange(null, timeoutMillis(), MILLISECONDS); 138 shouldThrow(); 139 } catch (TimeoutException success) {} 140 assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); 141 }}); 142 143 awaitTermination(t); 144 } 145 146 /** 147 * If one exchanging thread is interrupted, another succeeds. 148 */ testReplacementAfterExchange()149 public void testReplacementAfterExchange() { 150 final Exchanger<Item> e = new Exchanger<>(); 151 final CountDownLatch exchanged = new CountDownLatch(2); 152 final CountDownLatch interrupted = new CountDownLatch(1); 153 Thread t1 = newStartedThread(new CheckedInterruptedRunnable() { 154 public void realRun() throws InterruptedException { 155 assertSame(two, e.exchange(one)); 156 exchanged.countDown(); 157 e.exchange(two); 158 }}); 159 Thread t2 = newStartedThread(new CheckedRunnable() { 160 public void realRun() throws InterruptedException { 161 assertSame(one, e.exchange(two)); 162 exchanged.countDown(); 163 await(interrupted); 164 assertSame(three, e.exchange(one)); 165 }}); 166 Thread t3 = newStartedThread(new CheckedRunnable() { 167 public void realRun() throws InterruptedException { 168 await(interrupted); 169 assertSame(one, e.exchange(three)); 170 }}); 171 172 await(exchanged); 173 t1.interrupt(); 174 awaitTermination(t1); 175 interrupted.countDown(); 176 awaitTermination(t2); 177 awaitTermination(t3); 178 } 179 180 } 181