Java Exchanger并发类使用方法

简介

Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的。这里主要是两个线程之间交换持有的对象。当Exchanger在一个线程中调用exchange方法之后,会等待另外的线程调用同样的exchange方法。

两个线程都调用exchange方法之后,传入的参数就会交换。

类定义

public class Exchanger<V>

其中V表示需要交换的对象类型。

类继承

java.lang.Object
↳ java.util.concurrent.Exchanger<V>

Exchanger直接继承自Object。

构造函数

Exchanger()

Exchanger提供一个无参构造函数。

两个主要方法

public V exchange(V x) throws InterruptedException

当这个方法被调用的时候,当前线程将会等待直到其他的线程调用同样的方法。当其他的线程调用exchange之后,当前线程将会继续执行。

在等待过程中,如果有其他的线程interrupt当前线程,则会抛出InterruptedException。

public V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException

和第一个方法类似,区别是多了一个timeout时间。如果在timeout时间之内没有其他线程调用exchange方法,则会抛出TimeoutException。

具体的例子

我们先定义一个带交换的类:

@Data
public class CustBook {
  private String name;
}

然后定义两个Runnable,在run方法中调用exchange方法:

@Slf4j
public class ExchangerOne implements Runnable{

  Exchanger<CustBook> ex;

  ExchangerOne(Exchanger<CustBook> ex){
   this.ex=ex;
  }

  @Override
  public void run() {
  CustBook custBook= new CustBook();
    custBook.setName("book one");

    try {
      CustBook exhangeCustBook=ex.exchange(custBook);
      log.info(exhangeCustBook.getName());
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
@Slf4j
public class ExchangerTwo implements Runnable{

  Exchanger<CustBook> ex;

  ExchangerTwo(Exchanger<CustBook> ex){
   this.ex=ex;
  }

  @Override
  public void run() {
  CustBook custBook= new CustBook();
    custBook.setName("book two");

    try {
      CustBook exhangeCustBook=ex.exchange(custBook);
      log.info(exhangeCustBook.getName());
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

最后在主方法中调用:

public class ExchangerUsage {

  public static void main(String[] args) {
    Exchanger<CustBook> exchanger = new Exchanger<>();
    // Starting two threads
    new Thread(new ExchangerOne(exchanger)).start();
    new Thread(new ExchangerTwo(exchanger)).start();
  }
}

我们看下结果:

22:14:09.069 [Thread-1] INFO com.flydean.ExchangerTwo - book one
22:14:09.073 [Thread-0] INFO com.flydean.ExchangerOne - book two

可以看到对象已经被交换了。

结语

Exchanger在两个线程需要交换对象的时候非常好用。大家可以在实际工作生活中使用。

本文的例子https://github.com/ddean2009/learn-java-concurrency/tree/master/Exchanger

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java编程思想中关于并发的总结

    知识点摘抄 1.用并发解决的问题大体上可以分为"速度"和"设计可管理性"两种. 2.并发通常是提高运行在单处理器上的程序的性能. 这听起来有些违背直觉.如果你仔细考虑一下就会发现,在单处理器上运行的并发程序开销确实应该比该程序的所有部分都顺序执行的开销大,因为其中增加了所谓上下文切换的代价(从一个任务切换到另一个任务). 使这个问题变得有些不同的是阻塞.如果程序中的某个任务因为该线程控制之外的某些条件(通常是I/O)而导致不能继续执行,那么我们就说这个任务或线程阻塞

  • java 并发编程之共享变量的实现方法

    可见性 如果一个线程对共享变量值的修改, 能够及时的被其他线程看到, 叫做共享变量的可见性. Java 虚拟机规范试图定义一种 Java 内存模型 (JMM), 来屏蔽掉各种硬件和操作系统的内存访问差异, 让 Java 程序在各种平台上都能达到一致的内存访问效果. 简单来说, 由于 CPU 执行指令的速度是很快的, 但是内存访问的速度就慢了很多, 相差的不是一个数量级, 所以搞处理器的那群大佬们又在 CPU 里加了好几层高速缓存. 在 Java 内存模型里, 对上述的优化又进行了一波抽象. JM

  • 通俗易懂学习java并发工具类-Semaphore,Exchanger

    1. 控制资源并发访问--Semaphore Semaphore可以理解为信号量,用于控制资源能够被并发访问的线程数量,以保证多个线程能够合理的使用特定资源. Semaphore就相当于一个许可证,线程需要先通过acquire方法获取该许可证,该线程才能继续往下执行,否则只能在该方法出阻塞等待.当执行完业务功能后,需要通过release()方法将许可证归还,以便其他线程能够获得许可证继续执行. Semaphore可以用于做流量控制,特别是公共资源有限的应用场景,比如数据库连接.假如有多个线程读取

  • Java多线程编程之使用Exchanger数据交换实例

    用于实现两个人之间的数据交换,每个人在完成一定的事务后想与对方交换数据,第一个先拿出数据的人将一直等待第二个人拿着数据到来时,才能彼此交换数据. 复制代码 代码如下: package com.ljq.test.thread;   import java.util.concurrent.Exchanger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;   public cla

  • 浅析java并发中的Synchronized关键词

    如果在多线程的环境中,我们经常会遇到资源竞争的情况,比如多个线程要去同时修改同一个共享变量,这时候,就需要对资源的访问方法进行一定的处理,保证同一时间只有一个线程访问. java提供了synchronized关键字,方便我们实现上述操作. 为什么要同步 我们举个例子,我们创建一个类,提供了一个setSum的方法: public class SynchronizedMethods { private int sum = 0; public void calculate() { setSum(get

  • Java编程线程同步工具Exchanger的使用实例解析

    本文研究的主要是Java编程线程同步工具Exchanger的使用,下面看看具体内容. 如果两个线程在运行过程中需要交换彼此的信息,比如一个数据或者使用的空间,就需要用到Exchanger这个类,Exchanger为线程交换信息提供了非常方便的途径,它可以作为两个线程交换对象的同步点,只有当每个线程都在进入 exchange ()方法并给出对象时,才能接受其他线程返回时给出的对象. 每次只能两个线程交换数据,如果有多个线程,也只有两个能交换数据.下面看个通俗的例子:一手交钱一首交货! public

  • Java多线程并发生产者消费者设计模式实例解析

    一.两个线程一个生产者一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个. 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用标记或加锁机制. wait() / nofity() 方法是基类Object的两个方法,也就意味着所有Java类都会拥有这两个方法,这样,我们就可以为任何对象实现同步机制. wait()方法:当缓冲区已满/空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等待状态,让其他线程执行. not

  • Java Exchanger并发类使用方法

    简介 Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的.这里主要是两个线程之间交换持有的对象.当Exchanger在一个线程中调用exchange方法之后,会等待另外的线程调用同样的exchange方法. 两个线程都调用exchange方法之后,传入的参数就会交换. 类定义 public class Exchanger<V> 其中V表示需要交换的对象类型. 类继承 java.lang.Object ↳ java.util.concurrent.Excha

  • java.util.ArrayDeque类使用方法详解

    本文为大家介绍了java.util.ArrayDeque类使用方法,供大家参考,具体内容如下 1. ArrayDeque有两个类属性,head和tail,两个指针. 2. ArrayDeque通过一个数组作为载体,其中的数组元素在add等方法执行时不移动,发生变化的只是head和tail指针,而且指针是循环变化,数组容量不限制. 3. offer方法和add方法都是通过其中的addLast方法实现,每添加一个元素,就把元素加到数组的尾部,此时,head指针没有变化,而tail指针加一,因为指针是

  • java编程abstract类和方法详解

    抽象类和抽象方法常用知识点: (1)抽象类作为被继承类,子类必须实现抽象类中的所有抽象方法,除非子类也为抽象类. 也就是说,如果子类也为抽象类,可以不实现父类中的抽象方法.但是,如果有一个非抽象类 继承于抽象子类,需要实现抽象子类,抽象子类的抽象父类的所有抽象方法,新帐旧账一起算. (2)抽象类不能用final进行修饰. (3)抽象类不能被实例化,也就是说你用的时候不能通过new关键字创建. (4)抽象类中可以包含抽象方法和非抽象方法,抽象方法没有方法体,也就是没有具体实现, 只是定义了有什么功

  • Java中String类使用方法总结

    一.Java中关于String类的常用方法 本文只用来自己做笔记,随便写写,方便自己理解,谢谢各位的指正.下面是摘抄慕课的一部分 1.使用 substring(beginIndex , endIndex) 进行字符串截取时,包括 beginIndex 位置的字符,不包括 endIndex 位置的字符. 2.字符串 str 中字符的索引从0开始,范围为 0 到 str.length()-1 3.使用 indexOf 进行字符或字符串查找时,如果匹配返回位置索引:如果没有匹配结果,返回 -1 4.整

  • Java动态调用类中方法代码

    在Java中,调用类的方法有两种方式:对于静态方法可以直接使用类名调用,对于非静态方法必须使用类的对象调用.反射机制提供了比较另类的调用方式,可以根据需要指定要调用的方法,而不必在编程时确定.调用的方法不仅限于public的,还可以是private的.编写程序,使用反射机制调用Math类的静态方法sin()和非静态方法equals(). 思路如下:使用Math.class.getDeclaredMethod("sin", Double.TYPE);访问指定的方法,其中"sin

  • java.util.Collections类—emptyList()方法的使用

    目录 emptyList()方法的使用 Java Collections.emptyList()方法的注意事项 emptyList() Collections是列表的工具类,其中有好多方便实用的方法.主要是对列表的查找.替换.排序.反转等操作.今天介绍一下emptyList()方法的使用,因为这个方法有一个大坑! emptyList()方法的使用 通过java.util.Collections.emptyList()方法的相关源码可以得知它实际上就是返回了一个空的List,但是这个List和我们

  • Java定义画板类的方法

    在画图软件中,可以画出不同大小的圆形.矩形等几何图形.圆形都有半径,可以根据半径计算圆形的面积和周长,矩形都有宽和高,可以根据宽高来计算矩形的面积和周长. 编写Java程序: (1)分别设计实现圆形类.正方形类.长方形类,并根据文字描述合理设计类的成员属性和方法. (2)设计实现画板类,在画板类的main方法中 ①画一个圆形(即创建一个圆形对象,并给其成员属性赋值),然后调用方法获取它的面积和周长并打印: ②画一个正方形(即创建一个正方形对象,并给其成员属性赋值),然后调用方法获取它的面积和周长

  • Java 处理高并发负载类优化方法案例详解

    java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据) 一:高并发高负载类网站关注点之数据库 没错,首先是数据库,这是大多数应用所面临的首个SPOF.尤其是Web2.0的应用,数据库的响应是首先要解决的. 一般来说MySQL是最常用的,可能最初是一个mysql主机,当数据增加到100万以上,那么,MySQL的效能急剧下降.常用的优化措施是M-S(主-从)方式进行同步复制,将查询和操作和分别在不同的服务器上进行操作.我推荐的是M-M-Slaves

  • Java高并发BlockingQueue重要的实现类详解

    ArrayBlockingQueue 有界的阻塞队列,内部是一个数组,有边界的意思是:容量是有限的,必须进行初始化,指定它的容量大小,以先进先出的方式存储数据,最新插入的在对尾,最先移除的对象在头部. public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { /** 队列元素 */ final Object

  • Java 常见的并发问题处理方法总结

    好像挺久没有写博客了,趁着这段时间比较闲,特来总结一下在业务系统开发过程中遇到的并发问题及解决办法,希望能帮到大家

随机推荐