40 import java.lang.invoke.VarHandle;
41 import java.util.concurrent.locks.LockSupport;
42
43 /**
44 * A synchronization point at which threads can pair and swap elements
45 * within pairs. Each thread presents some object on entry to the
46 * {@link #exchange exchange} method, matches with a partner thread,
47 * and receives its partner's object on return. An Exchanger may be
48 * viewed as a bidirectional form of a {@link SynchronousQueue}.
49 * Exchangers may be useful in applications such as genetic algorithms
50 * and pipeline designs.
51 *
52 * <p><b>Sample Usage:</b>
53 * Here are the highlights of a class that uses an {@code Exchanger}
54 * to swap buffers between threads so that the thread filling the
55 * buffer gets a freshly emptied one when it needs it, handing off the
56 * filled one to the thread emptying the buffer.
57 * <pre> {@code
58 * class FillAndEmpty {
59 * Exchanger<DataBuffer> exchanger = new Exchanger<>();
60 * DataBuffer initialEmptyBuffer = ... a made-up type
61 * DataBuffer initialFullBuffer = ...
62 *
63 * class FillingLoop implements Runnable {
64 * public void run() {
65 * DataBuffer currentBuffer = initialEmptyBuffer;
66 * try {
67 * while (currentBuffer != null) {
68 * addToBuffer(currentBuffer);
69 * if (currentBuffer.isFull())
70 * currentBuffer = exchanger.exchange(currentBuffer);
71 * }
72 * } catch (InterruptedException ex) { ... handle ... }
73 * }
74 * }
75 *
76 * class EmptyingLoop implements Runnable {
77 * public void run() {
78 * DataBuffer currentBuffer = initialFullBuffer;
79 * try {
80 * while (currentBuffer != null) {
81 * takeFromBuffer(currentBuffer);
82 * if (currentBuffer.isEmpty())
83 * currentBuffer = exchanger.exchange(currentBuffer);
84 * }
85 * } catch (InterruptedException ex) { ... handle ...}
86 * }
87 * }
88 *
89 * void start() {
90 * new Thread(new FillingLoop()).start();
91 * new Thread(new EmptyingLoop()).start();
92 * }
|
40 import java.lang.invoke.VarHandle;
41 import java.util.concurrent.locks.LockSupport;
42
43 /**
44 * A synchronization point at which threads can pair and swap elements
45 * within pairs. Each thread presents some object on entry to the
46 * {@link #exchange exchange} method, matches with a partner thread,
47 * and receives its partner's object on return. An Exchanger may be
48 * viewed as a bidirectional form of a {@link SynchronousQueue}.
49 * Exchangers may be useful in applications such as genetic algorithms
50 * and pipeline designs.
51 *
52 * <p><b>Sample Usage:</b>
53 * Here are the highlights of a class that uses an {@code Exchanger}
54 * to swap buffers between threads so that the thread filling the
55 * buffer gets a freshly emptied one when it needs it, handing off the
56 * filled one to the thread emptying the buffer.
57 * <pre> {@code
58 * class FillAndEmpty {
59 * Exchanger<DataBuffer> exchanger = new Exchanger<>();
60 * DataBuffer initialEmptyBuffer = ...; // a made-up type
61 * DataBuffer initialFullBuffer = ...;
62 *
63 * class FillingLoop implements Runnable {
64 * public void run() {
65 * DataBuffer currentBuffer = initialEmptyBuffer;
66 * try {
67 * while (currentBuffer != null) {
68 * addToBuffer(currentBuffer);
69 * if (currentBuffer.isFull())
70 * currentBuffer = exchanger.exchange(currentBuffer);
71 * }
72 * } catch (InterruptedException ex) { ... handle ...}
73 * }
74 * }
75 *
76 * class EmptyingLoop implements Runnable {
77 * public void run() {
78 * DataBuffer currentBuffer = initialFullBuffer;
79 * try {
80 * while (currentBuffer != null) {
81 * takeFromBuffer(currentBuffer);
82 * if (currentBuffer.isEmpty())
83 * currentBuffer = exchanger.exchange(currentBuffer);
84 * }
85 * } catch (InterruptedException ex) { ... handle ...}
86 * }
87 * }
88 *
89 * void start() {
90 * new Thread(new FillingLoop()).start();
91 * new Thread(new EmptyingLoop()).start();
92 * }
|