blob: b1119803bc114f425e4be2ced69f9f9b1622d70e [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
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
9package jsr166;
10
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010011import static java.util.concurrent.TimeUnit.MILLISECONDS;
12
Calin Juravle8f0d92b2013-08-01 17:26:00 +010013import java.util.concurrent.CountDownLatch;
14import java.util.concurrent.Exchanger;
15import java.util.concurrent.TimeoutException;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010016
17import junit.framework.Test;
18import junit.framework.TestSuite;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010019
20public class ExchangerTest extends JSR166TestCase {
21
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010022 // 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() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000029 // return new TestSuite(ExchangerTest.class);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010030 // }
31
Calin Juravle8f0d92b2013-08-01 17:26:00 +010032 /**
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}