Thinking in Java學習筆記,使用Exchanger交換資源


生產者生產出的產品放入生產者隊列,消費者等待消費者隊列和生產者隊列完成交換


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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章