March 8, 2024

Exchanger in Java With Examples

Many synchronization aid were added as the part of java.util.concurrent package in Java 5 like CyclicBarrier, Semaphore. One more synchronization aid added as part of Java concurrency is Exchanger. In this post we’ll see what is Exchanger in Java, how does it work and an example of Exchanger.

Exchanger in Java Concurrency

Exchanger in Java is a synchronization aid that helps in exchanging the data between two threads. When two threads call exchange() method the objects supplied by these two threads are exchanged.

Exchanger in Java

Exchanger can be used in a Producer-Consumer scenario where a producer thread produces a buffer which can be exchanged with an empty buffer from consumer thread.

Java Exchanger class constructor

Exchanger class has only one constructor.

  • Exchanger()- Creates a new Exchanger.

Methods in Exchanger class

Exchanger class in Java has only one method exchange() which has two overloaded forms.

  • exchange(V 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.
  • exchange(V x, long timeout, TimeUnit 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.

Java Exchanger example

Here is an example of producer consumer threads where threads use Exchanger to exchange data. The data which is exchanged is of type DataBuffer.

DataBuffer.java
import java.util.ArrayList;
import java.util.List;

public class DataBuffer {
  private List data = new ArrayList<>();

  public String getData() {
    return data.remove(0);
  }
  public void addToBuffer(String str) {
    data.add(str);
  }
  public boolean isFull() {
    if(data.size() == 1) 
      return true;
    return false;
  }
}
public class ExchangerDemo {
  public static void main(String[] args) {
    Exchanger ex = new Exchanger();
    // Starting two threads
    new Thread(new Producer(ex)).start();
    new Thread(new Consumer(ex)).start();
  }
}
// Producer class
class Producer implements Runnable {
  Exchanger ex;
  DataBuffer producerBuffer;
  Producer(Exchanger ex){
    this.ex = ex;
  }
  @Override
  public void run() {
    DataBuffer producerBuffer = new DataBuffer();
    for(int i = 0; i < 3; i ++){
      producerBuffer.addToBuffer("Producer" + i);
      try {
        if (producerBuffer.isFull()) {
          // exchange
          producerBuffer = ex.exchange(producerBuffer);
        }
      } catch (InterruptedException e) {
        System.out.println(e);
      }
    }       
  }   
}
// Consumer class
class Consumer implements Runnable {
  Exchanger ex;
  DataBuffer consumerBuffer;
  Consumer(Exchanger ex){
    this.ex = ex;
  }
  @Override
  public void run() {
    DataBuffer consumerBuffer = new DataBuffer();
    for(int i = 0; i < 3; i ++){        	
      try {  
        System.out.println("waiting...");
        consumerBuffer = ex.exchange(consumerBuffer);
        System.out.println("Received- " + consumerBuffer.getData());
      } catch (InterruptedException e) {
        System.out.println(e);
      }
    }       
  }   
}
Output
waiting...
Received- Producer0
waiting...
Received- Producer1
waiting...
Received- Producer2

That's all for the topic Exchanger in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment