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'}