生产者生产出的产品放入生产者队列,消费者等待消费者队列和生产者队列完成交换
package com.test.concurrent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ExchangerDemo {
static int size=10;
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
List<Fat> produceList=new CopyOnWriteArrayList<Fat>();
List<Fat> consumeList=new CopyOnWriteArrayList<Fat>();
Exchanger<List<Fat>> xc=new Exchanger<List<Fat>>();
ExecutorService exec=Executors.newCachedThreadPool();
exec.execute(new ExchangerProducer(xc,BasicGenerator.create(Fat.class),produceList));
exec.execute(new ExchangerConsumer(consumeList,xc));
TimeUnit.SECONDS.sleep(5);
exec.shutdownNow();
}
}
class ExchangerProducer<T> implements Runnable{
private List<T> holder;
private Exchanger<List<T>> exchanger;
private Generator<T> generator;
public ExchangerProducer(Exchanger<List<T>> exchanger,Generator<T> generator,List<T> holder){
this.exchanger=exchanger;
this.holder=holder;
this.generator=generator;
}
@Override
public void run(){
try {
while(!Thread.interrupted()){
for(int i=0;i<ExchangerDemo.size;i++){
holder.add(generator.next());
}
holder=exchanger.exchange(holder);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ExchangerConsumer<T> implements Runnable{
private Exchanger<List<T>> exchanger;
private List<T> holder;
private volatile T value;
ExchangerConsumer(List<T> holder, Exchanger<List<T>> exchanger){
this.holder=holder;
this.exchanger=exchanger;
}
@Override
public void run(){
try{
while(!Thread.interrupted()){
holder=exchanger.exchange(holder);
for(T t:holder){
value=t;
holder.remove(t);
}
}
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Consume Final value: "+value);
}
}
class Fat{
private volatile double d; //prevent optimization
private static int counter=0;
private final int id=counter++;
public Fat(){
for(int i=0;i<10000;i++){
d+=(Math.PI+Math.E);
}
}
public String toString(){
return "Fat id: "+id+" D:"+d;
}
public void operation(){
System.out.println(this);
}
}
interface Generator<T>{
T next();
}
class BasicGenerator<T> implements Generator<T>{
private Class<T> type;
public BasicGenerator(Class<T> type){
this.type=type;
}
public T next(){
try {
return type.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static <T> Generator<T> create(Class<T> type){
return new BasicGenerator<T>(type);
}
}
输出:
java.lang.InterruptedException
at java.util.concurrent.Exchanger.exchange(Unknown Source)
at com.test.concurrent.ExchangerProducer.run(ExchangerDemo.java:43)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.InterruptedException
at java.util.concurrent.Exchanger.exchange(Unknown Source)
at com.test.concurrent.ExchangerConsumer.run(ExchangerDemo.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Consume Final value: Fat id: 319279 D:58598.74482048422