java并发编程实战手册第三章同步辅助类Exchanger

本实例使用Exchanger来演示一对一的生产者和消费者问题

.并发任务间的数据交换(生产者—消费模型(一对一))
本案例使用Exchanger同步辅助类实现,该类运行在并发任务之间交换数据。该类允许两个线程之间定义同步点,当两个线程都到达同步点的时候,它们交换数据结构,因此第一个线程
的数据结构进入到第二个线程中,同事第二个线程的数据结构进入到第一个线程中。

1.Consumer类

/**
 * 
 * @author fcs
 * @date 2015-5-2
 * 描述:并发任务间的数据交换
 * 说明:使用同步辅助工具Exchanger
 */
public class Consumer implements Runnable{
    private List<String> buffer;
    private final Exchanger<List<String>>  exchanger;

    public Consumer(List<String> buffer, Exchanger<List<String>> exchanger) {
        super();
        this.buffer = buffer;
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        int cycle = 0;
        for(int i =0;i< 10;i++){
            System.out.printf("Consumer: Cycle %d\n",cycle);
            //这里消费者要消费数据,就要先获得数据,调用exchange方法交换数据结构
            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Consumer size: "+buffer.size());
            //将生产者放入消费者buffer列表中的10个字符串打印到控制台,并从列表中删除,保持一个空列表
            for(int j =0 ;j < 10;j++){
                String message = buffer.get(0);
                System.out.println("Consumer: "+message);
                buffer.remove(0);
            }
            cycle++;
        }
    }
}

2.Producer类

public class Producer implements Runnable{

    private List<String> buffer;   //生产者和消费者用于交换的数据结构

    private final Exchanger<List<String>> exchanger;  //同步生产者和消费者的交换对象

    public Producer(List<String> buffer, Exchanger<List<String>> exchanger) {
        super();
        this.buffer = buffer;
        this.exchanger = exchanger;
    }


    @Override
    public void run() {
        int cycle = 1;
        for(int i =0;i< 10;i++){
            System.out.printf("Produceer: Cycle %d\n",cycle);
            for(int j =0 ;j < 10;j++){
                String message = "Event" +((i * 10)+j);
                System.out.printf("Producer :%s\n",message);
                buffer.add(message);
            }
            try{
                buffer = exchanger.exchange(buffer);   //该方法会抛出异常
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println("Producer: "+buffer.size());
        }
    }
}

3.测试类

/**
 * 
 * @author fcs
 * @date 2015-5-2
 * 描述:生产者---消费者(一对一)问题,使用同步辅助工具实现
 * 说明:
 */
public class Main {
    public static void main(String[] args) {
        List<String> buffer1 = new ArrayList<String>();
        List<String> buffer2 = new ArrayList<String>();

        //创建exchanger对象,用来同步生产者和消费者
        Exchanger<List<String>>  exchanger = new Exchanger<List<String>>();
        Producer producer = new Producer(buffer1,exchanger);
        Consumer consumer = new Consumer(buffer2,exchanger);
        Thread pthread = new Thread(producer);
        Thread cthread = new Thread(consumer);
        pthread.start();
        cthread.start();

    }
}

演示效果:
生产者消费者模型演示

5.Exchanger: 提供了两个线程之间的数据交换的同步机制。而其他的同步机制,则需要根据各自的上述特性来对其选择使用。我们需要根据应用程序的特性来选择合适的同步机制。
该类的主要方法:
exchange(): 等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。
exchange(V data,long time,TimeUnit unit):第一个传入参数的类型是V,即要交换的数据结构,这个方法被调用后,线程将休眠直到被中断,或者其他线程到达,或者已经耗费了指定的time值。

内存一致性效果:对于通过 Exchanger 成功交换对象的每对线程,每个线程中在 exchange() 之前的操作 happen-before 从另一线程中相应的 exchange() 返回的后续操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值