68 |
|
|
69 |
|
/** Holder for the item being exchanged */ |
70 |
|
private V item; |
71 |
< |
|
71 |
> |
|
72 |
|
/** |
73 |
|
* Arrival count transitions from 0 to 1 to 2 then back to 0 |
74 |
|
* during an exchange. |
88 |
|
while (arrivalCount == 2) { |
89 |
|
if (!timed) |
90 |
|
taken.await(); |
91 |
< |
else if (nanos > 0) |
91 |
> |
else if (nanos > 0) |
92 |
|
nanos = taken.awaitNanos(nanos); |
93 |
< |
else |
93 |
> |
else |
94 |
|
throw new TimeoutException(); |
95 |
|
} |
96 |
|
|
97 |
|
int count = ++arrivalCount; |
98 |
|
|
99 |
|
// If item is already waiting, replace it and signal other thread |
100 |
< |
if (count == 2) { |
100 |
> |
if (count == 2) { |
101 |
|
other = item; |
102 |
|
item = x; |
103 |
|
taken.signal(); |
109 |
|
|
110 |
|
item = x; |
111 |
|
InterruptedException interrupted = null; |
112 |
< |
try { |
112 |
> |
try { |
113 |
|
while (arrivalCount != 2) { |
114 |
|
if (!timed) |
115 |
|
taken.await(); |
116 |
< |
else if (nanos > 0) |
116 |
> |
else if (nanos > 0) |
117 |
|
nanos = taken.awaitNanos(nanos); |
118 |
< |
else |
118 |
> |
else |
119 |
|
break; // timed out |
120 |
|
} |
121 |
|
} catch (InterruptedException ie) { |
127 |
|
other = item; |
128 |
|
item = null; |
129 |
|
count = arrivalCount; |
130 |
< |
arrivalCount = 0; |
130 |
> |
arrivalCount = 0; |
131 |
|
taken.signal(); |
132 |
< |
|
132 |
> |
|
133 |
|
// If the other thread replaced item, then we must |
134 |
|
// continue even if cancelled. |
135 |
|
if (count == 2) { |
139 |
|
} |
140 |
|
|
141 |
|
// If no one is waiting for us, we can back out |
142 |
< |
if (interrupted != null) |
142 |
> |
if (interrupted != null) |
143 |
|
throw interrupted; |
144 |
|
else // must be timeout |
145 |
|
throw new TimeoutException(); |
149 |
|
} |
150 |
|
|
151 |
|
/** |
152 |
< |
* Create a new Exchanger. |
153 |
< |
**/ |
152 |
> |
* Creates a new Exchanger. |
153 |
> |
*/ |
154 |
|
public Exchanger() { |
155 |
|
} |
156 |
|
|
163 |
|
* it is resumed for thread scheduling purposes and receives the object |
164 |
|
* passed in by the current thread. The current thread returns immediately, |
165 |
|
* receiving the object passed to the exchange by that other thread. |
166 |
< |
* <p>If no other thread is already waiting at the exchange then the |
166 |
> |
* <p>If no other thread is already waiting at the exchange then the |
167 |
|
* current thread is disabled for thread scheduling purposes and lies |
168 |
|
* dormant until one of two things happens: |
169 |
|
* <ul> |
173 |
|
* </ul> |
174 |
|
* <p>If the current thread: |
175 |
|
* <ul> |
176 |
< |
* <li>has its interrupted status set on entry to this method; or |
176 |
> |
* <li>has its interrupted status set on entry to this method; or |
177 |
|
* <li>is {@link Thread#interrupt interrupted} while waiting |
178 |
< |
* for the exchange, |
178 |
> |
* for the exchange, |
179 |
|
* </ul> |
180 |
< |
* then {@link InterruptedException} is thrown and the current thread's |
181 |
< |
* interrupted status is cleared. |
180 |
> |
* then {@link InterruptedException} is thrown and the current thread's |
181 |
> |
* interrupted status is cleared. |
182 |
|
* |
183 |
|
* @param x the object to exchange |
184 |
|
* @return the object provided by the other thread. |
185 |
< |
* @throws InterruptedException if current thread was interrupted |
185 |
> |
* @throws InterruptedException if current thread was interrupted |
186 |
|
* while waiting |
187 |
< |
**/ |
187 |
> |
*/ |
188 |
|
public V exchange(V x) throws InterruptedException { |
189 |
|
try { |
190 |
|
return doExchange(x, false, 0); |
191 |
< |
} catch (TimeoutException cannotHappen) { |
191 |
> |
} catch (TimeoutException cannotHappen) { |
192 |
|
throw new Error(cannotHappen); |
193 |
|
} |
194 |
|
} |
205 |
|
* passed in by the current thread. The current thread returns immediately, |
206 |
|
* receiving the object passed to the exchange by that other thread. |
207 |
|
* |
208 |
< |
* <p>If no other thread is already waiting at the exchange then the |
208 |
> |
* <p>If no other thread is already waiting at the exchange then the |
209 |
|
* current thread is disabled for thread scheduling purposes and lies |
210 |
|
* dormant until one of three things happens: |
211 |
|
* <ul> |
216 |
|
* </ul> |
217 |
|
* <p>If the current thread: |
218 |
|
* <ul> |
219 |
< |
* <li>has its interrupted status set on entry to this method; or |
219 |
> |
* <li>has its interrupted status set on entry to this method; or |
220 |
|
* <li>is {@link Thread#interrupt interrupted} while waiting |
221 |
< |
* for the exchange, |
221 |
> |
* for the exchange, |
222 |
|
* </ul> |
223 |
< |
* then {@link InterruptedException} is thrown and the current thread's |
224 |
< |
* interrupted status is cleared. |
223 |
> |
* then {@link InterruptedException} is thrown and the current thread's |
224 |
> |
* interrupted status is cleared. |
225 |
|
* |
226 |
|
* <p>If the specified waiting time elapses then {@link TimeoutException} |
227 |
|
* is thrown. |
228 |
< |
* If the time is |
228 |
> |
* If the time is |
229 |
|
* less than or equal to zero, the method will not wait at all. |
230 |
|
* |
231 |
|
* @param x the object to exchange |
236 |
|
* while waiting |
237 |
|
* @throws TimeoutException if the specified waiting time elapses before |
238 |
|
* another thread enters the exchange. |
239 |
< |
**/ |
240 |
< |
public V exchange(V x, long timeout, TimeUnit unit) |
239 |
> |
*/ |
240 |
> |
public V exchange(V x, long timeout, TimeUnit unit) |
241 |
|
throws InterruptedException, TimeoutException { |
242 |
|
return doExchange(x, true, unit.toNanos(timeout)); |
243 |
|
} |
244 |
|
|
245 |
|
} |
246 |
– |
|
247 |
– |
|