Exchanger:JDK描述:可以在对中对元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给 exchange 方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象。Exchanger 可能被视为 SynchronousQueue 的双向形式。Exchanger 可能在应用程序(比如遗传算法和管道设计)中很有用。

我的理解就是:交换器类似于一个交易地点,先到的人(线程),等待后到的人,都到达后进行交易,等待时阻塞线程,交易后两个线程各自往下执行。

主要方法:exchange()

    • 等待另一个线程到达此交换点(除非当前线程被 中断),然后将给定的对象传送给该线程,并接收该线程的对象。
    • 如果另一个线程已经在交换点等待,则出于线程调度目的,继续执行此线程,并接收当前线程传入的对象。当前线程立即返回,接收其他线程传递的交换对象。
    • 如果还没有其他线程在交换点等待,则出于调度目的,禁用当前线程,且在发生以下两种情况之一

之前

    ,该线程将一直处于休眠状态:

    •   其他某个线程进入交换点;或者
    •   其他某个线程中断当前线程。

如果当前线程:

  • 在进入此方法时已经设置了该线程的中断状态;或者
  • 在等待交换时被中断

则抛出 InterruptedException,并且清除当前线程的已中断状态。

简单例子:
package com.houjun.current.newClassBank;

import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit; /**
* @Author: HouJun
* @Date: 2019/10/18 16:40
* @Description: 交换器测试
* @version: 1.0
*/
public class TestExchanger {
public static void main(String[] args) throws InterruptedException {
Exchanger<Integer> exchanger = new Exchanger<>();
new Producer("", exchanger).start();//启动生产者线程
new Consumer("", exchanger).start();//启动消费者线程
TimeUnit.SECONDS.sleep(1);
} static class Producer extends Thread {
private Exchanger<Integer> exchanger;//交换器对象泛型为Integer
private static int data = 0; Producer(String name, Exchanger<Integer> exchanger) {
super("Producer-" + name);//调用父类构造方法
this.exchanger = exchanger;//传入交换器对象
} @Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
TimeUnit.SECONDS.sleep(1);
data = i;
System.out.println(getName() + "交换前:" + data);
data = exchanger.exchange(data);//方法返回交换后的值
System.out.println(getName() + "交换后:" + data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} static class Consumer extends Thread {
private Exchanger<Integer> exchanger;
private static int data = 0; Consumer(String name, Exchanger<Integer> exchanger) {
super("Consumer-" + name);
this.exchanger = exchanger;
} @Override
public void run() {
while (true) {
data = 0;
System.out.println(getName() + "交换前:" + data);
try {
TimeUnit.SECONDS.sleep(1);
data = exchanger.exchange(data);//方法返回交换后的值
System.out.println(getName() + "交换后:" + data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

并发新构件之Exchanger:交换器的更多相关文章

  1. 并发新构件之DelayQueue:延时队列

    DelayQueue:延时队列,首先是一个队列,所以可以持有对象,但是仅限于实现了Delayed接口的对象.重写getDelay()和compareTo()(因为要比较)方法: 通俗来讲:延时队列的就 ...

  2. 并发新构件之CyclicBarrier

    CyclicBarrier:叫做循环栅栏,名字挺好听的.JDK描述:允许一组线程全部等待彼此达到共同屏障点的同步辅助. 循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此. 屏障被 ...

  3. 并发新构件之CountDownLatch

    CountDownLatch译为倒计时锁存器:JDK描述     :允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助. A CountDownLatch用给定的计数初始化. awai ...

  4. 并发新构件之Semaphore:信号量

    Semaphore :JDK描述,通常用于限制可以访问某些资源(物理或逻辑的)的线程数目.一句话说明了他的作用.信号量有一个虚拟的许可证池,new Semaphore(10):构造一个含有10个许可证 ...

  5. 并发新构件之PriorityBlockingQueue:优先阻塞队列

    PriorityBlockingQueue:优先阻塞队列:是带有优先级的阻塞队列,一个无界阻塞队列,它使用与类 PriorityQueue 相同的顺序规则,并且提供了阻塞获取操作.虽然此队列逻辑上是无 ...

  6. 转: 【Java并发编程】之二十一:并发新特性—阻塞队列和阻塞栈(含代码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17511147 阻塞队列 阻塞队列是Java5并发新特性中的内容,阻塞队列的接口是Java. ...

  7. 【Java并发编程】:并发新特性—塞队列和阻塞栈

    阻塞队列 阻塞队列是Java5并发新特性中的内容,阻塞队列的接口是Java.util.concurrent.BlockingQueue,它有多个实现类:ArrayBlockingQueue.Delay ...

  8. 并发新特性—Executor 框架与线程池

    兰亭风雨 · 更新于 2018-11-14 09:00:31 并发新特性-Executor 框架与线程池 Executor 框架简介 在 Java 5 之后,并发编程引入了一堆新的启动.调度和管理线程 ...

  9. Java核心-多线程-并发控制器-Exchanger交换器

    1.基本概念 Exchanger,从名字上理解就是交换.Exchanger用于在两个线程之间进行数据交换,注意也只能在两个线程之间进行数据交换. 线程会阻塞在Exchanger的exchange方法上 ...

随机推荐

  1. VisualStudio下std::string的内存布局

    主要成员 union _Bxty { // storage for small buffer or pointer to larger one _Elem _Buf[_BUF_SIZE]; _Elem ...

  2. Linux基础-命令概述

    概述 很多人可能在电视或电影中看到过类似的场景,黑客面对一个黑色的屏幕,上面飘着密密麻麻的字符,梆梆一顿敲,就完成了窃取资料的任务,是不是很帅!我们作为一个开发者, 即使不为了成为上述的人, 也需要会 ...

  3. python作业/练习/实战:3、实现商品管理的一个程序

    作业要求 实现一个商品管理的一个程序,运行程序有三个选项,输入1添加商品:输入2删除商品:输入3 查看商品信息1.添加商品: 商品名称:xx 商品如果已经存在,提示商品已存在 商品价格:xx数量只能为 ...

  4. Java异常处理教程

    异常是在没有定义正常执行路径时在Java程序的执行期间可能出现的条件.Java通过将执行操作的代码与处理错误的代码分离来处理错误. 当发生异常时,Java会创建一个包含有关异常的所有信息的对象,并将其 ...

  5. Java内部类成员

    内部类可以访问其所有实例成员,实例字段和其封闭类的实例方法.参考如下实例 - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 2 ...

  6. 洛谷 P4178 Tree

    #include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #inclu ...

  7. mysql在插入数据前判断是否存在数据

    记录一次mysql插入数据的操作,要先判断表中是否存在对应的值. 以往我们的操作都是先select,再insert,今天给大家分享另一种操作,一条sql语句来实现: inset into user(u ...

  8. Linux中目录结构以及VI编辑器常见的命令操作

    1.每个目录的详细介绍,先放一张目录的整体结构在这里 /bin:是Binary的缩写,用于存放经常使用的命令 /sbin:s代表Super User,用于存放系统管理员使用的命令 /home:存放普通 ...

  9. 热修复框架Tinker的从0到集成之路(转)

    转自:http://blog.csdn.net/lisdye2/article/details/54411727 热修复框架Tinker的从0到集成之路 转载请标明出处: http://blog.cs ...

  10. elasticsearch学习笔记001

    <Elasticsearch 核心技术与实战>课程Github代码 https://github.com/onebirdrocks/geektime-ELK 运行的环境: windows ...