1.含義ide
Exchanger是在兩個任務之間交換對象的柵欄。當這些任務進入柵欄是,他們各自擁有一個對象,當他們離開時,他們都擁有以前由對象持有的對象。測試
2.使用場景this
一個任務在建立對象,浙西對象的生產代價很高昂,而在另一個任務在消費這些對象。經過這種方式,能夠有更多的對象在被建立的同時被消費。線程
例子:對象
List作爲生產端和消費端要交換的對象接口
對象生成器接口rem
public interface Generator<T> { T next(); }
對象初始化類generator
public class BasicGenerator<T> implements Generator<T> { private Class<T> type; public BasicGenerator(Class<T> type) { this.type = type; } public T next() { try { return this.type.newInstance(); } catch (Exception var2) { throw new RuntimeException(var2); } } public static <T> Generator<T> create(Class<T> type) { return new BasicGenerator(type); } }
實體對象it
public class Fat { //保證線程可見性 private volatile double d; private static int counter = 0; private final int id = counter++; public Fat() { for (int i = 0; i < 10000; i++) { d += (Math.PI + Math.E) / (double)i; } } public void operation() { System.out.println(this); } public String toString() { return "Fat id:" + id; } }
生產端代碼:io
public class ExchangerProducer<T> implements Runnable{ private Exchanger<List<T>> exchanger; private Generator<T> generator; private List<T> holder; public ExchangerProducer(Exchanger<List<T>> exchanger, Generator<T> generator, List<T> holder) { this.exchanger = exchanger; this.generator = generator; this.holder = holder; } @Override public void run() { try { while (!Thread.interrupted()) { for (int i = 0; i < ExchangerDemo.size; i++) { T t = generator.next(); System.out.println("producer :" + t); holder.add(t); //生產端將list放入柵欄 holder = exchanger.exchange(holder); } } } catch (InterruptedException e) { e.printStackTrace(); } } }
消費端代碼:
public class ExchangerConsumer<T> implements Runnable{ private Exchanger<List<T>> exchanger; private List<T> holder; private volatile T value; public ExchangerConsumer(Exchanger<List<T>> exchanger, List<T> holder) { this.exchanger = exchanger; this.holder = holder; } @Override public void run() { try { while(!Thread.interrupted()) { //消費端獲取柵欄中list holder = exchanger.exchange(holder); //清除list中數據 for (T x : holder) { System.out.println("consumer :" + x); value = x; holder.remove(x); } } }catch (InterruptedException e) { System.err.println("OK to terminate this way."); } System.out.println("Final value:" + value); } }
測試代碼:
public class ExchangerDemo { static int size = 10; static int delay = 1; 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<List<Fat>> xc = new Exchanger<>(); List<Fat> productList = new CopyOnWriteArrayList<>(); List<Fat> consumerList = new CopyOnWriteArrayList<>(); exec.execute(new ExchangerProducer<Fat>(xc, BasicGenerator.create(Fat.class), productList)); exec.execute(new ExchangerConsumer<Fat>(xc, consumerList)); TimeUnit.SECONDS.sleep(delay); exec.shutdownNow(); } }