//: concurrency/ExchangerDemo.java // ©2015 MindView LLC: see Copyright.txt import java.util.concurrent.*; import net.mindview.util.*; import java.util.*; class ExchangerProducer implements Runnable { private Generator generator; private Exchanger> exchanger; private List holder; ExchangerProducer(Exchanger> exchg, Generator gen, List holder) { exchanger = exchg; generator = gen; this.holder = holder; } @Override public void run() { try { while(!Thread.interrupted()) { for(int i = 0; i < ExchangerDemo.size; i++) holder.add(generator.next()); // Exchange full for empty: holder = exchanger.exchange(holder); } } catch(InterruptedException e) { // OK to terminate this way. } } } class ExchangerConsumer implements Runnable { private Exchanger> exchanger; private List holder; private volatile T value; ExchangerConsumer(Exchanger> ex, List holder){ exchanger = ex; this.holder = holder; } @Override public void run() { try { while(!Thread.interrupted()) { holder = exchanger.exchange(holder); for(T x : holder) { value = x; // Fetch out value holder.remove(x); // OK for CopyOnWriteArrayList } } } catch(InterruptedException e) { // OK to terminate this way. } System.out.println("Final value: " + value); } } public class ExchangerDemo { static int size = 10; static int delay = 5; // Seconds public static void main(String[] args) throws Exception { if(args.length > 0) size = new Integer(args[0]); if(args.length > 1) delay = new Integer(args[1]); ExecutorService exec = Executors.newCachedThreadPool(); Exchanger> xc = new Exchanger<>(); List producerList = new CopyOnWriteArrayList<>(), consumerList = new CopyOnWriteArrayList<>(); exec.execute(new ExchangerProducer<>(xc, BasicGenerator.create(Fat.class), producerList)); exec.execute( new ExchangerConsumer<>(xc,consumerList)); TimeUnit.SECONDS.sleep(delay); exec.shutdownNow(); } } /* Output: (Sample) Final value: Fat id: 29999 *///:~