zoukankan      html  css  js  c++  java
  • Java并发编程--6.Exchanger线程间交换数据

    在两个线程之间定义同步点,当两个线程都到达同步点时,他们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,第二个线程的数据结构进入到第一个线程中

    在生产者-消费者情境模式中它包含了一个数缓冲区,一个或者多个生产者,一个或者多个消费中

    下面是生产者和消费者的示例:

    /**
     * 生产者和消费者交换数据
     */
    public class MyExchanger {
        public static void main(String[] args) {
            Exchanger<List<String>> exchanger = new Exchanger<List<String>>();
            
            Producer1 producer = new Producer1(new ArrayList<String>(), exchanger);
            Consumer1 consumer = new Consumer1(new ArrayList<String>(), exchanger);
            
            new Thread(producer).start();
            new Thread(consumer).start();
        }
    }
    
    /** 生产者线程*/
     class Producer1 implements Runnable{
        
        /**
         * 存储交换的数据
         */
        private List<String> buffer;
        
        /**
         * 和消费者要交换的对象
         */
        private final Exchanger<List<String>> exchanger;
        
        Producer1(List<String> buffer,Exchanger<List<String>> exchanger){
            this.buffer = buffer;
            this.exchanger = exchanger;
        }
        
        @Override
        public void run() {
            for(int i = 0 ; i < 2 ; i++){
                    String message = "" + i ;
                    System.out.println("Produce的数据 : " + message);
                    buffer.add(message);
                
                //调用exchange()与消费者进行数据交换
                try {
                    buffer = exchanger.exchange(buffer);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            System.out.println("Produce收到来自Consumer的数据的长度 : " + buffer.size());
        }
    }
     
    /** 消费者线程*/ 
    class Consumer1 implements Runnable{
            private List<String> buffer;
            
            private final Exchanger<List<String>> exchanger;
            
            public Consumer1(List<String> buffer,Exchanger<List<String>> exchanger){
                this.buffer = buffer;
                this.exchanger = exchanger;
            }
            
            @Override
            public void run() {
                for(int i = 0 ; i < 2 ; i++){
                    //调用exchange()与消费者进行数据交换
                    try {
                        buffer = exchanger.exchange(buffer);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                    for(int j = 0 ; j < buffer.size() ; j++){
                        System.out.println("Consumer收到来自Produce的数据 : " + buffer.get(0));
                        buffer.remove(0);
                    }
                }
                
                System.out.println("Consumer清空数据");
            }
        }

    控制台输出:

    Produce的数据 : 0
    Consumer收到来自Produce的数据 : 0
    Produce的数据 : 1
    Produce收到来自Consumer的数据的长度 : 0
    Consumer收到来自Produce的数据 : 1
    Consumer清空数据

    在Exchanger中,如果一个线程已经到达了exchanger节点时,对于它的伙伴节点的情况有三种:

    1、如果它的伙伴节点在该线程到达之间已经调用了exchanger方法,则它会唤醒它的伙伴然后进行数据交换,得到各自数据返回。

    2、如果它的伙伴节点还没有到达交换点,则该线程将会被挂起,等待它的伙伴节点到达被唤醒,完成数据交换。

    3、如果当前线程被中断了则抛出异常,或者等待超时了,则抛出超时异常

  • 相关阅读:
    论文笔记之:Speed Up Tracking by Ignoring Features
    深度学习中常见的几个基础概念
    (转)The AlphaGo Replication Wiki
    论文笔记之:Co-saliency Detection via A Self-paced Multiple-instance Learning Framework
    (转)CVPR 2016 Visual Tracking Paper Review
    论文笔记之:Generative Adversarial Text to Image Synthesis
    论文笔记之:Conditional Generative Adversarial Nets
    论文笔记之:Progressive Neural Network Google DeepMind
    (转)Let’s make a DQN 系列
    论文阅读之:Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network
  • 原文地址:https://www.cnblogs.com/liuconglin/p/6710688.html
Copyright © 2011-2022 走看看