Java Exchanger栅栏

1.含义

Exchanger是在两个任务之间交换对象的栅栏。当这些任务进入栅栏是,他们各自拥有一个对象,当他们离开时,他们都拥有之前由对象持有的对象。

2.使用场景

一个任务在创建对象,浙西对象的生产代价很高昂,而在另外一个任务在消费这些对象。通过这种方式,可以有更多的对象在被创建的同时被消费。

例子:

List做为生产端和消费端要交换的对象

对象生成器接口

public interface Generator<T> {
    T next();
}

对象初始化类

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);
    }
}

实体对象

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 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();
    }
}

猜你喜欢

转载自my.oschina.net/u/1017791/blog/2967451