Thread Conncurrent Java Book

Exchanger class simplifies the exchange of data between two threads. Exchanger waits until two separate threads call its exchange( ) method. When that occurs, it exchanges the data supplied by the threads.
Exchanger is a generic class that is declared as shown here:

Exchanger

V specifies the type of the data being exchanged.
The only method defined by Exchanger is exchange( ), which has the two forms shown here:
V exchange(V buffer) throws InterruptedException
V exchange(V buffer, long wait, TimeUnit tu) throws InterruptedException, TimeoutException
buffer is a reference to the data to exchange. The data received from the other thread is returned.
The second form of exchange( ) allows a time-out period to be specified.
exchange( ) won't succeed until it has been called on the same Exchanger object by two separate threads. exchange( ) synchronizes the exchange of the data.

// An example of Exchanger.
import java.util.Date;
import java.util.concurrent.Exchanger;
public class Main {
public static void main(String args[]) {
Exchanger exgr = new Exchanger();
new Consumer(exgr);
new Producer(exgr);
}
}
class Producer implements Runnable {
Exchanger ex;
Producer(Exchanger c) {
ex = c;
new Thread(this).start();
}
public void run() {
for (int i = 0; i < 5; i++) {
try {
System.out.println("giving:"+ new Date());
String str = ex.exchange(new Date()+"");
System.out.println("Producer got:"+ str);
} catch (Exception exc) {
System.out.println(exc);
}
}
}
}
class Consumer implements Runnable {
Exchanger ex;
Consumer(Exchanger c) {
ex = c;
new Thread(this).start();
}
public void run() {
for (int i = 0; i < 5; i++) {
try {
String str = ex.exchange("Consumer Success");
System.out.println("Consumer Got: " + str);
} catch (Exception exc) {
System.out.println(exc);
}
}
}
}