The Java Exchanger class allows the interchange of data between two concurrent tasks.
Exchanger can create a synchronization point between two threads.
When the two threads arrive to this point, they interchange a data structure.
As the Exchanger class only synchronizes two threads, you can use it if you have a producer-consumer problem with one producer and one consumer.
import java.util.ArrayList; import java.util.List; import java.util.concurrent.Exchanger; public class Main { public static void main(String[] args) { List<String> buffer1 = new ArrayList<>(); List<String> buffer2 = new ArrayList<>(); Exchanger<List<String>> exchanger = new Exchanger<>(); Producer producer = new Producer(buffer1, exchanger); Consumer consumer = new Consumer(buffer2, exchanger); Thread threadProducer = new Thread(producer); Thread threadConsumer = new Thread(consumer); threadProducer.start();/*from w ww.j a va 2 s . c o m*/ threadConsumer.start(); } } class Consumer implements Runnable { private List<String> buffer; private final Exchanger<List<String>> exchanger; public Consumer(List<String> buffer, Exchanger<List<String>> exchanger) { this.buffer = buffer; this.exchanger = exchanger; } @Override public void run() { int cycle = 1; for (int i = 0; i < 10; i++) { System.out.printf("Consumer: Cycle %d\n", cycle); try { buffer = exchanger.exchange(buffer); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("Consumer: %d\n", buffer.size()); for (int j = 0; j < 10; j++) { String message = buffer.get(0); System.out.printf("Consumer: %s\n", message); buffer.remove(0); } cycle++; } } } class Producer implements Runnable { private List<String> buffer; private final Exchanger<List<String>> exchanger; public Producer(List<String> buffer, Exchanger<List<String>> exchanger) { this.buffer = buffer; this.exchanger = exchanger; } @Override public void run() { int cycle = 1; for (int i = 0; i < 10; i++) { System.out.printf("Producer: Cycle %d\n", cycle); for (int j = 0; j < 10; j++) { String message = "Event " + ((i * 10) + j); System.out.printf("Producer: %s\n", message); buffer.add(message); } try { buffer = exchanger.exchange(buffer); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("Producer: %d\n", buffer.size()); cycle++; } } }