Java Exchanger

Exchanger is a synchronization mechanism provided by Java's java.util.concurrent package. It allows two threads to exchange objects of the same type, providing a point of data transfer between the two threads. This article will provide an overview of Exchanger, explain its usage, and provide code examples.

Introduction to Exchanger

Exchanger is a class that facilitates the exchange of objects between two threads. It provides a synchronization point where two threads can wait for each other and exchange objects when both threads have reached the synchronization point.

The key features of Exchanger are:

  • It works with only two threads.
  • It provides a exchange() method to exchange objects between the two threads.
  • It blocks the calling thread until both threads have reached the synchronization point.
  • It can be used in scenarios where two threads need to exchange data or coordinate their actions.

How Exchanger Works

Exchanger works by providing a synchronization point where two threads can meet and exchange objects. The following state diagram illustrates the basic flow of Exchanger:

stateDiagram
    [*] --> Thread1
    Thread1 --> ExchangePoint
    ExchangePoint --> Thread2
    Thread2 --> [*]

Here's how Exchanger works step-by-step:

  1. Thread 1 and Thread 2 both start executing.
  2. Thread 1 reaches the Exchanger and calls the exchange() method, providing an object to exchange.
  3. Thread 1 blocks and waits for Thread 2 to reach the Exchanger.
  4. Thread 2 reaches the Exchanger and calls the exchange() method, providing another object to exchange.
  5. Thread 2 blocks and waits for Thread 1 to complete the exchange.
  6. The objects provided by Thread 1 and Thread 2 are exchanged.
  7. Thread 1 and Thread 2 resume execution with the exchanged objects.

Using Exchanger in Java

To use Exchanger, you need to follow these steps:

  1. Create an instance of Exchanger, specifying the type of objects to be exchanged. For example, Exchanger<String> can be used to exchange String objects.
  2. Implement the logic for each thread. Each thread should call the exchange() method to exchange objects.
  3. Start the threads and let them reach the Exchanger.

Here's a code example that demonstrates the usage of Exchanger:

import java.util.concurrent.Exchanger;

public class ExchangerExample {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<>();

        Thread thread1 = new Thread(() -> {
            try {
                String message = "Hello from Thread 1";
                System.out.println("Thread 1: Sending message - " + message);
                String receivedMessage = exchanger.exchange(message);
                System.out.println("Thread 1: Received message - " + receivedMessage);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                String message = "Hello from Thread 2";
                System.out.println("Thread 2: Sending message - " + message);
                String receivedMessage = exchanger.exchange(message);
                System.out.println("Thread 2: Received message - " + receivedMessage);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
    }
}

In this example, Thread 1 and Thread 2 exchange messages using the Exchanger. Each thread prints the message it sends and the message it receives after the exchange is complete.

When you run this code, you will see the following output:

Thread 1: Sending message - Hello from Thread 1
Thread 2: Sending message - Hello from Thread 2
Thread 2: Received message - Hello from Thread 1
Thread 1: Received message - Hello from Thread 2

As you can see, Thread 1 sends "Hello from Thread 1" and receives "Hello from Thread 2", while Thread 2 sends "Hello from Thread 2" and receives "Hello from Thread 1". The messages are successfully exchanged between the two threads.

Conclusion

Exchanger is a useful synchronization mechanism in Java that allows two threads to exchange objects of the same type. It provides a synchronization point where the threads can meet and exchange objects. This article provided an overview of Exchanger, explained its usage, and provided a code example. By using Exchanger, you can coordinate the actions of two threads and exchange data between them effectively.