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

并发编程-concurrent指南-交换机Exchanger的更多相关文章

  1. 并发编程-concurrent指南-原子操作类-AtomicInteger

    在java并发编程中,会出现++,--等操作,但是这些不是原子性操作,这在线程安全上面就会出现相应的问题.因此java提供了相应类的原子性操作类. 1.AtomicInteger

  2. 并发编程-concurrent指南-线程池ExecutorService的实例

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...

  3. 并发编程-concurrent指南-计数器CountDownLatch

    java.util.concurrent.CountDownLatch 是一个并发构造,它允许一个或多个线程等待一系列指定操作的完成. CountDownLatch 以一个给定的数量初始化.count ...

  4. 并发编程-concurrent指南-ConcurrentMap

    ConcurrentMap 是个接口,你想要使用它的话就得使用它的实现类之一. ConcurrentMap,它是一个接口,是一个能够支持并发访问的java.util.map集合: 在原有java.ut ...

  5. 并发编程-concurrent指南-阻塞双端队列-链阻塞双端队列LinkedBlockingDeque

    LinkedBlockingDeque是双向链表实现的阻塞队列.该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除): 在不能够插入元素时,它将阻塞住试图插入元 ...

  6. 并发编程-concurrent指南-阻塞队列-链表阻塞队列LinkedBlockingQueue

    LinkedBlockingQueue是一个基于链表的阻塞队列. 由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选. LinkedBlocki ...

  7. 并发编程-concurrent指南-原子操作类-AtomicLong

    可以用原子方式更新的 long 值.有关原子变量属性的描述,请参阅 java.util.concurrent.atomic 包规范.AtomicLong 可用在应用程序中(如以原子方式增加的序列号), ...

  8. 并发编程-concurrent指南-原子操作类-AtomicBoolean

    类AtomicBoolean

  9. 并发编程-concurrent指南-ReadWriteLock-ReentrantReadWriteLock(可重入读写锁)

    几个线程都申请读锁,都能获取: import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantRea ...

随机推荐

  1. WPF版的HideCaret()

    原文:WPF版的HideCaret() WPF版的HideCaret() 周银辉 事情是这样的: 一般说来,对于那些拥有句柄的TextBox(RichTextBox同理)控件,比如win32的,Win ...

  2. bigdata_mac下安装spark_scala

    Java 下载安装Mac对应版本的JDK. Apache-spark $ brew update $ brew info apache-spark $ brew install apache-spar ...

  3. RDIFramework.NET框架SOA解(集Windows服务、WinForm形式和IIS发布形式)-分布式应用程序

    RDIFramework.NET框架SOA解决方式(集Windows服务.WinForm形式与IIS形式公布)-分布式应用 RDIFramework.NET,基于.NET的高速信息化系统开发.整合框架 ...

  4. 去掉 Windows 中控件的虚线框(当当 element == QStyle::PE_FrameFocusRect 时,直接返回,不绘制虚线框)

    在 Windows 中,控件得到焦点的时候,会显示一个虚线框,很多时候觉得不好看,通过自定义 QProxyStyle 就可以把这个虚线框去掉. 1 2 3 4 5 6 7 8 9 10 11 12 1 ...

  5. Wrapped的返回值取值

    Bared   Wrapped   using Newtonsoft.Json; using Newtonsoft.Json.Linq; string str = JsonConvert.Serial ...

  6. XF 标签和文本控件

    <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http:/ ...

  7. Lexer的设计--下(5)

    一个礼拜之后我终于从成都回来了, 从今天开始更新会恢复... 一点小的改进 写lex()的时候距离我上一次写已经一个礼拜了, 所以我回顾了一下之前的代码, 发现还是有瑕疵. 比如考虑到一个较短的程序, ...

  8. ASP.NET Core 2 学习笔记(一)开始

    原文:ASP.NET Core 2 学习笔记(一)开始 来势汹汹的.NET Core似乎要取代.NET Framework,ASP.NET也随之发布.NET Core版本.虽然名称沿用ASP.NET, ...

  9. TCPClient组件和TCPServer组件的主要方法和属性

    IdTCPClient属性1 : IOHandler 如果有相应的输入/输出操作,那么IOHandler相对应的组件或接口将提供一个虚拟/抽象的输入/输出接口给相应的网络连接2 : Intercept ...

  10. Tomcat cache 缓存 编译

    http://tomcat.apache.org/tomcat-7.0-doc/jasper-howto.html development - Is Jasper used in developmen ...