exchange method, matches with a partner thread,
and receives its partner's object on return. An Exchanger may be
viewed as a bidirectional form of a SynchronousQueue.
Exchangers may be useful in applications such as genetic algorithms
and pipeline designs.
Sample Usage:
Here are the highlights of a class that uses an Exchanger
to swap buffers between threads so that the thread filling the
buffer gets a freshly emptied one when it needs it, handing off the
filled one to the thread emptying the buffer.
class FillAndEmpty {
Exchanger<DataBuffer> exchanger = new Exchanger<>();
DataBuffer initialEmptyBuffer = ...; // a made-up type
DataBuffer initialFullBuffer = ...;
class FillingLoop implements Runnable {
public void run() {
DataBuffer currentBuffer = initialEmptyBuffer;
try {
while (currentBuffer != null) {
addToBuffer(currentBuffer);
if (currentBuffer.isFull())
currentBuffer = exchanger.exchange(currentBuffer);
}
} catch (InterruptedException ex) { ... handle ...}
}
}
class EmptyingLoop implements Runnable {
public void run() {
DataBuffer currentBuffer = initialFullBuffer;
try {
while (currentBuffer != null) {
takeFromBuffer(currentBuffer);
if (currentBuffer.isEmpty())
currentBuffer = exchanger.exchange(currentBuffer);
}
} catch (InterruptedException ex) { ... handle ...}
}
}
void start() {
new Thread(new FillingLoop()).start();
new Thread(new EmptyingLoop()).start();
}
}
Memory consistency effects: For each pair of threads that
successfully exchange objects via an Exchanger, actions
prior to the exchange() in each thread
happen-before
those subsequent to a return from the corresponding exchange()
in the other thread.
| Modifier and Type | Class and Description |
|---|---|
| pack-priv static class | Exchanger.
Nodes hold partially exchanged data, plus other per-thread bookkeeping. |
| pack-priv static class | Exchanger.
The corresponding thread local class |
| pack-priv static class | Exchanger.
Padded arena cells to avoid false-sharing memory contention |
| Modifier and Type | Field and Description |
|---|---|
| private static final VarHandle | |
| private final Exchanger. | arena
Elimination array; element accesses use emulation of volatile gets and CAS. |
| private volatile int | bound
The index of the largest valid arena position. |
| private static final VarHandle | |
| private static final VarHandle | |
| private static final VarHandle | |
| private static final int | MMASK
The maximum supported arena index. |
| private final int | ncpu
Number of cores, for sizing and spin control. |
| private static final Exchanger. | participant
The participant thread-locals. |
| private static final int | SEQ
Unit for sequence/version bits of bound field. |
| private static final int | SPINS
The bound for spins while waiting for a match before either blocking or possibly shrinking arena. |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public V | Returns: the object provided by the other threadthe object to exchange x)Waits for another thread to arrive at this exchange point (unless the current thread is interrupted), and then transfers the given object to it, receiving its object in return. |
| public V | Returns: the object provided by the other threadthe object to exchange x, long the maximum time to wait timeout, TimeUnit the time unit of the unit)timeout argumentWaits for another thread to arrive at this exchange point (unless the current thread is interrupted or the specified waiting time elapses), and then transfers the given object to it, receiving its object in return. |
| private final V | Returns: the other thread's itemthe item to exchange x, long if zero, untimed, else timeout deadline deadline)Exchange function. |
| AA | back to summary |
|---|---|
| private static final VarHandle AA | |
| arena | back to summary |
|---|---|
| private final Exchanger. Elimination array; element accesses use emulation of volatile gets and CAS. | |
| bound | back to summary |
|---|---|
| private volatile int bound The index of the largest valid arena position. | |
| BOUND | back to summary |
|---|---|
| private static final VarHandle BOUND | |
| ENTRY | back to summary |
|---|---|
| private static final VarHandle ENTRY | |
| MATCH | back to summary |
|---|---|
| private static final VarHandle MATCH | |
| MMASK | back to summary |
|---|---|
| private static final int MMASK The maximum supported arena index. The maximum allocatable arena size is MMASK + 1. Must be a power of two minus one. The cap of 255 (0xff) more than suffices for the expected scaling limits of the main algorithms. | |
| ncpu | back to summary |
|---|---|
| private final int ncpu Number of cores, for sizing and spin control. Computed only upon construction. | |
| participant | back to summary |
|---|---|
| private static final Exchanger. The participant thread-locals. Because it is impossible to exchange, we also use this reference for dealing with null user arguments that are translated in and out of this value surrounding use. | |
| SEQ | back to summary |
|---|---|
| private static final int SEQ Unit for sequence/version bits of bound field. Each successful change to the bound also adds SEQ. | |
| SPINS | back to summary |
|---|---|
| private static final int SPINS The bound for spins while waiting for a match before either blocking or possibly shrinking arena. | |
| Exchanger | back to summary |
|---|---|
| public Exchanger() Creates a new Exchanger. | |
| exchange | back to summary |
|---|---|
| public V exchange(V x) throws InterruptedException Waits for another thread to arrive at this exchange point (unless the current thread is interrupted), and then transfers the given object to it, receiving its object in return. If another thread is already waiting at the exchange point then it is resumed for thread scheduling purposes and receives the object passed in by the current thread. The current thread returns immediately, receiving the object passed to the exchange by that other thread. If no other thread is already waiting at the exchange then the current thread is disabled for thread scheduling purposes and lies dormant until one of two things happens:
If the current thread:
InterruptedException is thrown and the current thread's
interrupted status is cleared.
| |
| exchange | back to summary |
|---|---|
| public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException Waits for another thread to arrive at this exchange point (unless the current thread is interrupted or the specified waiting time elapses), and then transfers the given object to it, receiving its object in return. If another thread is already waiting at the exchange point then it is resumed for thread scheduling purposes and receives the object passed in by the current thread. The current thread returns immediately, receiving the object passed to the exchange by that other thread. If no other thread is already waiting at the exchange then the current thread is disabled for thread scheduling purposes and lies dormant until one of three things happens:
If the current thread:
InterruptedException is thrown and the current thread's
interrupted status is cleared.
If the specified waiting time elapses then
| |
| xchg | back to summary |
|---|---|
| private final V xchg(V x, long deadline) throws InterruptedException, TimeoutException Exchange function. See above for explanation.
| |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv int | |
| pack-priv Object | |
| pack-priv volatile Object | |
| pack-priv volatile Thread | |
| pack-priv long |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| index | back to summary |
|---|---|
| pack-priv int index | |
| item | back to summary |
|---|---|
| pack-priv Object item | |
| match | back to summary |
|---|---|
| pack-priv volatile Object match | |
| parked | back to summary |
|---|---|
| pack-priv volatile Thread parked | |
| seed | back to summary |
|---|---|
| pack-priv long seed | |
| Node | back to summary |
|---|---|
| pack-priv Node() | |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public Exchanger. | initialValue()
Overrides java. Returns the current thread's "initial value" for this thread-local variable. |
| Participant | back to summary |
|---|---|
| pack-priv Participant() | |
| initialValue | back to summary |
|---|---|
| public Exchanger. Overrides java. Doc from java. Returns the current thread's "initial value" for this
thread-local variable. This method will be invoked the first
time a thread accesses the variable with the | |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| entry | back to summary |
|---|---|
| pack-priv Exchanger. | |
| Slot | back to summary |
|---|---|
| pack-priv Slot() | |