Exchanger

Exchanger  is a thread-synchronization construct that lets a pair of threads exchange data items. An exchanger is similar to a cyclic barrier whose count is set to 2 but also supports exchange of data when both threads reach the barrier.

Exchanger can be handy in solving Producer Consumer pattern where Producer and consumer threads can exchange their data.

The java.util.concurrent.Exchanger<V> class implements an exchanger. This class provides an Exchanger() constructor for initializing an exchanger that describes an exchange point and a pair of exchange() methods for performing an exchange.

Exchanger has 2 method exchange (V x ) and V exchange(V x, long timeout, TimeUnit unit) .

exchange() method enables two threads to exchange their data between each other in java.
If current thread is first one to call exchange() method then it will until one of following things happen:

  • Some other thread calls exchange() method in java, or
  • Some other thread interrupts the current thread in java, or
If some other thread has already called exchanger() method then it resumes its execution and following things happen -
  • waiting thread is resumed and receives data from current thread in java.
  • current thread receives data from that waiting thread and it returns immediately in java.

V exchange(V x, long timeout, TimeUnit unit) also behave the same as exchange() method , with the restriction that it wait for other thread untill a specified timeout.

Lets see an example to make the concept more clear :

ExchangerExample.java
public class ExchangerExample {

    public  static void main(String args[]){
        Exchanger exchanger = new Exchanger();
        Thread t1= new MyThread(exchanger,"I like coffee");
        Thread t2 = new MyThread(exchanger, "I like tea");
        t1.start();
        t2.start();
    }
}

MyThread.java
public class MyThread extends Thread  {

    Exchanger exchanger;
    String message;

    MyThread(Exchanger exchanger, String message){
        this.exchanger=exchanger;
        this.message=message;
    }

    @Override
    public void run(){
        try{
            System.out.println(this.getName()+" message: "+ message);
            //exchange message
            message = exchanger.exchange(message);
            System.out.println(this.getName()+" message: "+message);
        }catch (Exception e){
        }
    }
}

Output:
Thread-0 message: I like coffee
Thread-1 message: I like tea
Thread-0 message: I like tea
Thread-1 message: I like coffee


Explanation : We have created 2 thread and passed exchanger object in them. Once thread-0 call exchange() method and reach the exchanger point , it wait for other thread-1 to call the exchange() method and exchange the message.Once both the thread reach the same exchange point , they exchange their message.

Producer Consumer problem using Exchanger :

ProducerConsumerExchanger.java
public class ProducerConsumerExachanger {

    public static void main(String[] args) {
        Exchanger exchanger=new Exchanger();
        System.out.println("Exchanger has been created");
        Producer prod=new Producer(exchanger);
        Consumer cons=new Consumer(exchanger);

        Thread prodThread=new Thread(prod,"prodThread");
        Thread consThread=new Thread(cons,"consThread");

        prodThread.start();
        consThread.start();

    }
}

Producer.java
class Producer implements Runnable{

    Exchanger exchanger;
    String str;
    Producer(Exchanger exchanger){
        str=new String();
        this.exchanger=exchanger;
    }

    @Override
    public void run(){

        for(int i=1;i<=5;i++){
            str+=i;
            System.out.println("Produced : "+i);
            try {
                str= exchanger.exchange(str);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}


Comments

Popular posts from this blog

Deploy standalone Spring MVC Application in Docker Container

Refactor Code : Separate Query from Modifier

HTTP : Must known Protocol (Part 1)