1.含义
Exchanger是在两个任务之间交换对象的栅栏。当这些任务进入栅栏是,他们各自拥有一个对象,当他们离开时,他们都拥有之前由对象持有的对象。
2.使用场景
一个任务在创建对象,浙西对象的生产代价很高昂,而在另外一个任务在消费这些对象。通过这种方式,可以有更多的对象在被创建的同时被消费。
例子:
List做为生产端和消费端要交换的对象
对象生成器接口
public interface Generator{ T next();}
对象初始化类
public class BasicGeneratorimplements Generator { private Class type; public BasicGenerator(Class type) { this.type = type; } public T next() { try { return this.type.newInstance(); } catch (Exception var2) { throw new RuntimeException(var2); } } public static Generator create(Class type) { return new BasicGenerator(type); }}
实体对象
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; }}
生产端代码:
public class ExchangerProducerimplements Runnable{ private Exchanger
> exchanger; private Generator generator; private List holder; public ExchangerProducer(Exchanger
> exchanger, Generator generator, List 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 ExchangerConsumerimplements Runnable{ private Exchanger
> exchanger; private List holder; private volatile T value; public ExchangerConsumer(Exchanger
> exchanger, List 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
> xc = new Exchanger<>(); List productList = new CopyOnWriteArrayList<>(); List consumerList = new CopyOnWriteArrayList<>(); exec.execute(new ExchangerProducer (xc, BasicGenerator.create(Fat.class), productList)); exec.execute(new ExchangerConsumer (xc, consumerList)); TimeUnit.SECONDS.sleep(delay); exec.shutdownNow(); }}