Close

Java - Exchanger

[Last Updated: May 24, 2018]

Exchanger is a synchronization point at which threads can pair and swap elements within pairs.
An Exchanger may be viewed as a bidirectional form of a SynchronousQueue.
Exchanger#exchange(data) waits for another thread to also invoke exchange(data). It is similar to Queue#poll() method but is synchronized and is bidirectional. This method is a way to transfer the given object between threads.

Example

public class ExchangerExample {

    public static void main(String... args) throws InterruptedException {
        Exchanger<MyExchangeData> exchanger = new Exchanger<MyExchangeData>();

        ExecutorService es = Executors.newFixedThreadPool(2);
        //party1
        es.execute(new Runnable() {
            @Override
            public void run() {

                try {
                    for (int i = 1; i <= 5; i++) {
                        System.out.println("-- party1 next --");
                        MyExchangeData data = new MyExchangeData("msg from party1 " + i);
                        System.out.println("party1 calling exchange() with data: "+data);
                        MyExchangeData exchange = exchanger.exchange(data);
                        System.out.println("party1 exchange() returned and received: " + exchange);
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    System.err.println(e);
                }
            }
        });

        Thread.sleep(1000);
        //party2
        es.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    for (int i = 1; i <= 5; i++) {
                        System.out.println("-- party2 next --");
                        MyExchangeData data = new MyExchangeData("msg from party2 " + i);
                        System.out.println("party2 calling exchange() with data: "+data);
                        MyExchangeData exchange = exchanger.exchange(data);
                        System.out.println("party2 exchange() returned and received: " + exchange);
                        Thread.sleep(1000);
                    }
                    es.shutdown();

                } catch (InterruptedException e) {
                    System.err.println(e);
                }
            }
        });
    }

    private static class MyExchangeData {
        private String msg;
        public MyExchangeData(String msg) {
            this.msg = msg;
        }
        @Override
        public String toString() {
            return "MyExchangeData{" +
                    "msg='" + msg + '\'' +
                    '}';
        }
    }
}
-- party1 next --
party1 calling exchange() with data: MyExchangeData{msg='msg from party1 1'}
-- party2 next --
party2 calling exchange() with data: MyExchangeData{msg='msg from party2 1'}
party2 exchange() returned and received: MyExchangeData{msg='msg from party1 1'}
party1 exchange() returned and received: MyExchangeData{msg='msg from party2 1'}
-- party2 next --
-- party1 next --
party2 calling exchange() with data: MyExchangeData{msg='msg from party2 2'}
party1 calling exchange() with data: MyExchangeData{msg='msg from party1 2'}
party1 exchange() returned and received: MyExchangeData{msg='msg from party2 2'}
party2 exchange() returned and received: MyExchangeData{msg='msg from party1 2'}
-- party1 next --
-- party2 next --
party2 calling exchange() with data: MyExchangeData{msg='msg from party2 3'}
party1 calling exchange() with data: MyExchangeData{msg='msg from party1 3'}
party1 exchange() returned and received: MyExchangeData{msg='msg from party2 3'}
party2 exchange() returned and received: MyExchangeData{msg='msg from party1 3'}
-- party1 next --
-- party2 next --
party1 calling exchange() with data: MyExchangeData{msg='msg from party1 4'}
party2 calling exchange() with data: MyExchangeData{msg='msg from party2 4'}
party1 exchange() returned and received: MyExchangeData{msg='msg from party2 4'}
party2 exchange() returned and received: MyExchangeData{msg='msg from party1 4'}
-- party2 next --
-- party1 next --
party2 calling exchange() with data: MyExchangeData{msg='msg from party2 5'}
party1 calling exchange() with data: MyExchangeData{msg='msg from party1 5'}
party1 exchange() returned and received: MyExchangeData{msg='msg from party2 5'}
party2 exchange() returned and received: MyExchangeData{msg='msg from party1 5'}

Example Project

Dependencies and Technologies Used:

  • JDK 1.8
  • Maven 3.3.9

Example Project

Dependencies and Technologies Used:

  • JDK 1.8
  • Maven 3.3.9

Exchanger Example Select All Download
  • java-concurrency-exchanger-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ExchangerExample.java

    See Also