zoukankan      html  css  js  c++  java
  • 并发编程-concurrent指南-交换机Exchanger

    java.util.concurrent包中的Exchanger类可用于两个线程之间交换信息。可简单地将Exchanger对象理解为一个包含两个格子的容器,通过exchanger方法可以向两个格子中填充信息。当两个格子中的均被填充时,该对象会自动将两个格子的信息交换,然后返回给线程,从而实现两个线程的信息交换。
    另外需要注意的是,Exchanger类仅可用作两个线程的信息交换,当超过两个线程调用同一个exchanger对象时,得到的结果是随机的,exchanger对象仅关心其包含的两个“格子”是否已被填充数据,当两个格子都填充数据完成时,该对象就认为线程之间已经配对成功,然后开始执行数据交换操作。

    Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据。

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

    它典型的应用场景是:一个任务在创建对象,这些对象的生产代价很高昂,而另一个任务在消费这些对象。通过这种方式,可以有更多的对象在被创建的同时被消费。

    public class ExchangerRunnable implements Runnable{
        private Exchanger<String> exchanger;
        private String data;
        private int random;
        public ExchangerRunnable(Exchanger exchanger,String data,int random){
            this.exchanger = exchanger;
            this.data = data;
            this.random = random;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+",数据:"+data);
            try {
                TimeUnit.SECONDS.sleep(random);
                String data_new = exchanger.exchange(data);
                System.out.println(Thread.currentThread().getName()+",数据:"+data_new);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public class Main {
        public static void main(String[] args) {
            //交换机
            Exchanger exchanger = new Exchanger();
    
            ExchangerRunnable exchangerRunnable = new ExchangerRunnable(exchanger,"aa",3);
            ExchangerRunnable exchangerRunnable1 = new ExchangerRunnable(exchanger,"bb",10);
    
            new Thread(exchangerRunnable).start();
            new Thread(exchangerRunnable1).start();
        }
    }

    结果:

    Thread-0,数据:aa
    Thread-1,数据:bb
    Thread-0,数据:bb
    Thread-1,数据:aa

    注意:

    1.当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行。

    2.多个线程时,有且只有两个线程进入数据交换。

    源码地址:https://github.com/qjm201000/concurrent_exchanger.git

  • 相关阅读:
    bug、兼容性、适配问题
    关于daterangepicker取消默认值的设置
    重构-改善既有代码设计
    iphoneX 适配
    汇编语言(2)程序表示
    汇编语言(1)基础理论
    css 边框颜色渐变的半圆
    横向时间轴(进度条)
    pdf中内嵌字体问题
    jabRef里引用的相邻同名作者变横线
  • 原文地址:https://www.cnblogs.com/qjm201000/p/10152679.html
Copyright © 2011-2022 走看看