2.11 线程间的数据交换

线程间的数据交换

如果要在两个线程间同步数据,使用Java并发API提供了的 Exchanger类会很方便。 Exchanger类允许在并发任务之间交换数据,它允许在两个线程之间定义同步点,当两个线程都达到同步点时进行数据交换:第一个线程的数据结构进入到第二个线程,第二个线程的数据结构进入到第一个线程。

本文用 Exchanger来解决一对一的生产者-消费者问题,示例代码如下:
public class ExchangerDemo {
    public static void main(String[] args){
        Exchanger<List<String>> exchanger = new Exchanger<List<String>>();

        System.out.println("main;创建生产者和消费线程");
        Thread t1 = new Thread(new ExchangerProducer(exchanger));
        Thread t2 = new Thread(new ExchangerCustomer(exchanger));

        System.out.println("main;启动生产者和消费线程");
        t1.start();
        t2.start();
    }
}

class ExchangerCustomer implements Runnable{
    private Exchanger<List<String>> exchanger;
    private List<String> buffer;

    ExchangerCustomer(Exchanger<List<String>> exchanger) {
        this.exchanger = exchanger;
        buffer = new ArrayList<String>(10);
    }

    @Override
    public void run() {
        for(int i=0; i<3; i++){
            System.out.println("消费者:第" + i + "次数据交换");
            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("消费者:完成数据交换。来自生产者的数据个数:" + buffer.size());
            for(int j=0; j<buffer.size();j++){
                System.out.print(buffer.get(j)+",");
            }
            System.out.println();
            System.out.println("消费者:清空消费者数据。");
            buffer.clear();;
        }
    }
}

class ExchangerProducer implements Runnable{

    private Exchanger<List<String>> exchanger;
    private List<String> buffer;

    ExchangerProducer(Exchanger<List<String>> exchanger) {
        this.exchanger = exchanger;
        buffer = new ArrayList<String>(10);
    }

    @Override
    public void run() {
        for(int i=0; i<3; i++){
            System.out.println("生产者:第" + i + "次数据交换");
            //准备10个交换数据
            for(int j=0; j<10 ;j++){
                String msg = "Data:" + (i*10+j);
                buffer.add(msg);
            }
            System.out.println("生产者:进行数据交换");
            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("生产者:完成数据交换。来自消费者的数据个数:" + buffer.size());
        }
    }
}

程序运行日志:

main;创建生产者和消费线程
main;启动生产者和消费线程
生产者:第0次数据交换
生产者:进行数据交换
消费者:第0次数据交换
生产者:完成数据交换。来自消费者的数据个数:0
生产者:第1次数据交换
生产者:进行数据交换
消费者:完成数据交换。来自生产者的数据个数:10
Data:0,Data:1,Data:2,Data:3,Data:4,Data:5,Data:6,Data:7,Data:8,Data:9,
消费者:清空消费者数据。
消费者:第1次数据交换
消费者:完成数据交换。来自生产者的数据个数:10
生产者:完成数据交换。来自消费者的数据个数:0
Data:10,生产者:第2次数据交换
Data:11,Data:12,生产者:进行数据交换
Data:13,Data:14,Data:15,Data:16,Data:17,Data:18,Data:19,
消费者:清空消费者数据。
消费者:第2次数据交换
消费者:完成数据交换。来自生产者的数据个数:10
Data:20,Data:21,生产者:完成数据交换。来自消费者的数据个数:0
Data:22,Data:23,Data:24,Data:25,Data:26,Data:27,Data:28,Data:29,
消费者:清空消费者数据。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值