APIdia Launch Partner
Top Description Inners Fields Constructors Methods
java.util.concurrent

public Class Exchanger<V>

extends Object
Class Inheritance
Type Parameters
<V>
The type of objects that may be exchanged
Imports
jdk.internal.invoke.MhUtil, java.lang.invoke.MethodHandles, .VarHandle, java.util.concurrent.locks.LockSupport

A synchronization point at which threads can pair and swap elements within pairs. Each thread presents some object on entry to the 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.

Author
Doug Lea and Bill Scherer and Michael Scott
Since
1.5

Nested and Inner Type Summary

Modifier and TypeClass and Description
pack-priv static class
Exchanger.Node

Nodes hold partially exchanged data, plus other per-thread bookkeeping.

pack-priv static class
Exchanger.Participant

The corresponding thread local class

pack-priv static class
Exchanger.Slot

Padded arena cells to avoid false-sharing memory contention

Field Summary

Modifier and TypeField and Description
private static final VarHandle
private final Exchanger.Slot[]
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
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.

Constructor Summary

AccessConstructor and Description
public
Exchanger()

Creates a new Exchanger.

Method Summary

Modifier and TypeMethod and Description
public V

Returns:

the object provided by the other thread
exchange
(V
the 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 thread
exchange
(V
the object to exchange
x
,
long
the maximum time to wait
timeout
,
TimeUnit
the time unit of the timeout argument
unit
)

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.

private final V

Returns:

the other thread's item
xchg
(V
the item to exchange
x
,
long
if zero, untimed, else timeout deadline
deadline
)

Exchange function.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

AAback to summary
private static final VarHandle AA
arenaback to summary
private final Exchanger.Slot[] arena

Elimination array; element accesses use emulation of volatile gets and CAS.

boundback to summary
private volatile int bound

The index of the largest valid arena position.

BOUNDback to summary
private static final VarHandle BOUND
ENTRYback to summary
private static final VarHandle ENTRY
MATCHback to summary
private static final VarHandle MATCH
MMASKback 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.

ncpuback to summary
private final int ncpu

Number of cores, for sizing and spin control. Computed only upon construction.

participantback to summary
private static final Exchanger.Participant participant

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.

SEQback to summary
private static final int SEQ

Unit for sequence/version bits of bound field. Each successful change to the bound also adds SEQ.

SPINSback to summary
private static final int SPINS

The bound for spins while waiting for a match before either blocking or possibly shrinking arena.

Constructor Detail

Exchangerback to summary
public Exchanger()

Creates a new Exchanger.

Method Detail

exchangeback 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:

  • Some other thread enters the exchange; or
  • Some other thread interrupts the current thread.

If the current thread:

  • has its interrupted status set on entry to this method; or
  • is interrupted while waiting for the exchange,
then InterruptedException is thrown and the current thread's interrupted status is cleared.
Parameters
x:V

the object to exchange

Returns:V

the object provided by the other thread

Exceptions
InterruptedException:
if the current thread was interrupted while waiting
exchangeback 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:

  • Some other thread enters the exchange; or
  • Some other thread interrupts the current thread; or
  • The specified waiting time elapses.

If the current thread:

  • has its interrupted status set on entry to this method; or
  • is interrupted while waiting for the exchange,
then InterruptedException is thrown and the current thread's interrupted status is cleared.

If the specified waiting time elapses then TimeoutException is thrown. If the time is less than or equal to zero, the method will not wait at all.

Parameters
x:V

the object to exchange

timeout:long

the maximum time to wait

unit:TimeUnit

the time unit of the timeout argument

Returns:V

the object provided by the other thread

Exceptions
InterruptedException:
if the current thread was interrupted while waiting
TimeoutException:
if the specified waiting time elapses before another thread enters the exchange
xchgback to summary
private final V xchg(V x, long deadline) throws InterruptedException, TimeoutException

Exchange function. See above for explanation.

Parameters
x:V

the item to exchange

deadline:long

if zero, untimed, else timeout deadline

Returns:V

the other thread's item

Exceptions
InterruptedException:
if interrupted while waiting
TimeoutException:
if deadline nonzero and timed out
java.util.concurrent back to summary

pack-priv final Class Exchanger.Node

extends Object
Class Inheritance

Nodes hold partially exchanged data, plus other per-thread bookkeeping.

Field Summary

Modifier and TypeField and Description
pack-priv int
pack-priv Object
pack-priv volatile Object
pack-priv volatile Thread
pack-priv long

Constructor Summary

AccessConstructor and Description
pack-priv
Node()

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

indexback to summary
pack-priv int index
itemback to summary
pack-priv Object item
matchback to summary
pack-priv volatile Object match
parkedback to summary
pack-priv volatile Thread parked
seedback to summary
pack-priv long seed

Constructor Detail

Nodeback to summary
pack-priv Node()
java.util.concurrent back to summary

pack-priv final Class Exchanger.Participant

extends ThreadLocal<Exchanger.Node>
Class Inheritance

The corresponding thread local class

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public Exchanger.Node
initialValue()

Overrides java.lang.ThreadLocal.initialValue.

Returns the current thread's "initial value" for this thread-local variable.

Inherited from java.lang.ThreadLocal:
getremovesetwithInitial

Constructor Detail

Participantback to summary
pack-priv Participant()

Method Detail

initialValueback to summary
public Exchanger.Node initialValue()

Overrides java.lang.ThreadLocal.initialValue.

Doc from java.lang.ThreadLocal.initialValue.

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 get method, unless the thread previously invoked the set method, in which case the initialValue method will not be invoked for the thread. Normally, this method is invoked at most once per thread, but it may be invoked again in case of subsequent invocations of remove followed by get.

java.util.concurrent back to summary

pack-priv final Class Exchanger.Slot

extends Object
Class Inheritance
Annotations
@Contended

Padded arena cells to avoid false-sharing memory contention

Field Summary

Modifier and TypeField and Description
pack-priv Exchanger.Node

Constructor Summary

AccessConstructor and Description
pack-priv
Slot()

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

entryback to summary
pack-priv Exchanger.Node entry

Constructor Detail

Slotback to summary
pack-priv Slot()