What is an Exchanger used for? — Cracked Java
// Concurrency & Multithreading · Synchronizers: Latch, Barrier, Semaphore, Phaser
SeniorTheory

What is an Exchanger used for?

An Exchanger<T> is a synchronization point where exactly two threads swap objects: each calls exchange(myItem), blocks until the partner arrives, and then each receives the other's item. It is a two-party rendezvous with a payload — the only synchronizer designed for paired data hand-off rather than counting.

How it works

exchange(x) blocks until another thread also calls exchange(y) on the same Exchanger. At that instant both calls return: the first thread gets y, the second gets x. There is a timed overload, exchange(x, timeout, unit), that throws TimeoutException if no partner shows up. It is strictly two threads at a time — if three arrive, they pair off in some order; an exchanger does not coordinate more than a pair per swap.

Exchanger<List<String>> exchanger = new Exchanger<>();

// Producer thread: fills a buffer, swaps it for an empty one
Runnable producer = () -> {
    List<String> buffer = new ArrayList<>();
    try {
        while (true) {
            fill(buffer);
            buffer = exchanger.exchange(buffer); // get the empty one back
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
};

// Consumer thread: drains a buffer, swaps it back empty
Runnable consumer = () -> {
    List<String> buffer = new ArrayList<>();
    try {
        while (true) {
            buffer = exchanger.exchange(buffer); // get the full one
            drain(buffer);                       // then return it emptied
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
};

The canonical use case

The textbook pattern is double buffering in a producer/consumer pipeline: the producer fills buffer A while the consumer drains buffer B, then they exchange so the producer gets the now-empty B and the consumer gets the full A. No shared queue, no copying — the buffers are simply traded. This can reduce allocation pressure compared to a BlockingQueue because the same two buffers are recycled.

Mark your status