如何通过示例使用Java中的Exchanger

大家好,如果您在并发Java应用程序中工作,那么您可能听说过java.util.concurrent包的Exchanger类。 Java中的Exchanger是Java 1.5中与CountDownLatch , CyclicBarrier和Semaphores一起引入的另一个并发或同步实用程序。 顾名思义, Exchanger允许两个线程在集合点或集合点见面并交换数据。 的
java.util.Exchanger是一个参数类,它定义并保存要交换的对象的类型。 它有一个重载的方法,称为
exchange() ,用于在线程之间交换对象。 这是一种阻塞方法,这意味着线程将调用 exchange()方法在交换点等待,直到另一个线程到达。 一旦另一个线程到达,两个线程都交换对象并从此方法返回。 交换方法的重载版本接受其他 TimeUnit对象,并等待直到超时。

顺便说一句,您还可以中断在交换点等待其他参与者的线程。 与CountDownLatchCyclicBarrierSemaphoreExchanger实用程序只能同步两个线程,这使其非常适合解决经典的生产者-消费者问题 。

在本Java并发教程中,您将通过使用Exchanger实现生产者-消费者设计模式来学习如何在Java中使用Exchanger。 顺便说一句,我假设您熟悉Java编程语法和语义,如果您是Java的完整入门者,那么您可能会很难理解这个示例。

Exchanger类是一个易于理解和使用的简单同步实用程序。 在最后的两个并发教程中,我们使用了wait和notify解决了生产者使用者(请参阅此处 ),还使用BlockingQueue实现了生产者-消费者 ,现在该使用Exchanger来实现了。

在此Java并发性教程中, 我们将创建一个生产者和一个使用者线程 ,它们将使用Exchanger实用程序类交换缓冲区。

通常,这是Exchanger的工作方式:

1.首先,创建一个Exchange对象,例如Exchanger<Deque<Long>> stringExchanger = new Exchanger<>() ; 这定义了线程之间将交换什么类型的对象。 在这种情况下,两个线程将交换包含长值的Deque对象。

2.当线程A准备交换其缓冲区或对象时,它将调用
Exchanger.exchange()方法。 这是一种阻塞方法 , 线程A将被阻塞,直到线程B到来并将其对象传输到线程A 为止,否则线程A被中断或超时。

3.线程B准备就绪时,它还会调用exchange()方法。 现在,线程A和B互相交换对象,并从交换方法返回。

4.交换完成后,线程A具有线程B的对象,反之亦然。

同样,我想强调Java并发技能的重要性,并敦促每个Java开发人员花一些时间来掌握Java并发类。

带有Exchanger并发的Java程序

 import java.util.ArrayDeque;  import java.util.Deque;  import java.util.concurrent.Exchanger;   /** * Exchanger Example in Java. Exchanger allows two Threads to meet at exchange * point and exchange data structure or objects. In this Java program, exchanger * is used to exchange buffer between producer and consumer.  * @author Javin Paul  */   public class JavaExchangerTutorail {    public static void main(String args[]) throws InterruptedException {   //Creating Exchanger to exchange String object with other thread final Exchanger> exchanger = new Exchanger>();   Thread producer = new Thread( "Producer : " ){  @Override public void run(){  ArrayDeque(); Deque stack = new ArrayDeque();  //producer thread insert elments into stack while (stack.isEmpty()) { 
 stack.add(System.nanoTime()% 1000 ); //if stack is not empty then exchange it to consumer thread  try {  System.out.println(Thread.currentThread().getName() + " ready to exchange : " + stack); 
 <br> 
 // Exchanger return other Thread's object stack = exchanger.exchange(stack); System.out.println(Thread.currentThread().getName() + " got : " + stack);  } catch (InterruptedException ie) { ie.printStackTrace(); } (InterruptedException ie) { ie.printStackTrace(); }  }  }  };    Thread consumer = new Thread( "Consumer : " ){  @Override  public void run(){  ArrayDeque(); Deque stack = new ArrayDeque();   //consumer thread takes object from stack and prints  do { //if stack is empty then exchange it to producer for refill try {  System.out.println(Thread.currentThread().getName() + " ready to exchange : " + stack); stack = exchanger.exchange(stack); System.out.println(Thread.currentThread().getName() + " got : " + stack); stack.remove();  } catch (InterruptedException ie) { ie.printStackTrace(); } (InterruptedException ie) { ie.printStackTrace(); }  } while (stack.isEmpty()) ;    }  };    producer.start(); 
 <br> 
 //sleeping before starting consumer to give producer time to produce Thread.sleep( 1000 ); 
 consumer.start();    }     }     Output:   Producer : ready to exchange : [ 247 ]   Consumer : ready to exchange : []   Producer : got : []   Consumer : got : [ 247 ]   Producer : ready to exchange : [ 692 ]   Consumer : ready to exchange : []   Consumer : got : [ 692 ]   Consumer : ready to exchange : []   Producer : got : [] 
 <br> 

代码和输出说明

如果看上面的示例,所有代码都在main方法内部。 之所以使Exchanger实例成为最终实例,是因为我们要从匿名内部类访问它们,并且只能从匿名内部类访问最终局部变量。

后来,我们创建了两个线程, ProducerConsumer 。 生产者检查队列,如果队列为空,则将当前nano时间的最后三位相加并调用exchange()方法。

现在,直到消费者线程到达交换点,我的意思是直到生产者线程调用exchange()方法,生产者线程才会被阻塞。

使用者到达后,双方互相交换堆栈并从exchange()方法返回。 此时,生产者有一个空的消费者堆栈,而消费者有一个非空的生产者堆栈,我的意思是,他们有彼此的对象

为了理解哪个线程正在交换哪个堆栈,我们在每个线程交换之前和之后打印堆栈的内容。 如果您查看输出,这是不言自明的。

顺便提一下,与线程一样,不能保证以相同的顺序获得输出。 在第三次迭代中,您可以看到使用者具有一个已清空的堆栈,甚至可以在安排生产者线程并从交换方法返回之前,准备交换空堆栈。

这就是如何在Java中使用Exchanger的全部内容。 交换器类是一个很好的简单同步工具,非常适合于协调两个线程。 应该使用交换器来实现具有一个生产者和一个消费者的生产者-消费者模式。 如果您想了解有关Java并发类的更多信息,建议您检查以下资源:

进阶学习

完整的Java Masterclass Java多线程,并发和性能优化 Java并发实践–本书 将并发和多线程应用于常见的Java模式

您可能喜欢的其他Java并发文章

  • 2020 Java开发人员路线图 ( 路线图 )
  • Java并发之前发生了什么? ( 回答 )
  • 10个Java多线程和并发最佳实践( 文章 )
  • Java中的前50个多线程和并发问题( 问题 )
  • 掌握Java并发性的5大书籍( 书籍 )
  • 10个面向初学者和中级开发者的免费Java课程( 课程 )
  • 如何避免Java死锁? ( 回答 )
  • 了解Java程序中的数据和代码流( 回答 )
  • Java Concurrency in Practice是否在2020年仍然有效( 回答 )
  • Java中CyclicBarrier和CountDownLatch之间的区别? ( 回答 )
  • 10个技巧,成为2020年的一个更好的Java开发( 提示 )
  • 如何使用wait-notify在Java中进行线程间通信? ( 回答 )
  • 深入学习Java多线程的前5门课程( 课程 )

感谢您到目前为止阅读本文。 如果您喜欢此Java并发教程,请与您的朋友和同事分享。 如果您有任何问题或反馈,请留下笔记。

PS –如果您是Java世界的新手,并且想与Concurrency一起学习核心概念,但是想找一些免费的入门课程,那么您也可以在Udemy上查看此免费的Java Multithreading课程 。 这也是学习Java并发性的一门很好的免费课程。

翻译自: https://www.javacodegeeks.com/2020/05/how-to-use-exchanger-in-java-with-example.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340266.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python里写在文件的指定行_python文件操作如何写在指定的行

常常在操作文件时我们只想在某一行的插入信息&#xff0c;可以先将文件读入列表中&#xff0c;利用列表的下标插入文本&#xff0c;之后再重新写入文件。但是弊端是&#xff0c;如果文件量太大列表的性能可能不是很高。python代码&#xff1a;#codingutf-8lines[]fopen("d…

外星人跑深度学习_上海港汇外星人店,51M2020开光追和DLSS2.0畅玩《赛博朋克2077》...

上海外星人港汇恒隆广场店是外星人布局上海的首家3.0店面&#xff0c;坐落在繁华的徐家汇商圈港汇恒隆广场南座6楼。门店传承了外星人高端高品质&#xff0c;以服务客户为宗旨&#xff0c;立足上海&#xff0c;辐射周边&#xff0c;服务所有外星人客户。近日&#xff0c;让全球…

python flask html模板,python flask web开发实战 Jinja2模板

templates/index.htmlHello World!templates/user.htmlHello, {{ name }}!渲染模板&#xff1a;from flask import Flask,render_templateapp.route(/)def index():return render_template(index.html)app.route(/user/)def user(name):return render_template(user.html, name…

gwt前台开发_为GWT设置开发环境

gwt前台开发介绍 这是旨在用Java开发跨平台移动应用程序的系列文章的一部分 。 在此博客文章中&#xff0c;我们将了解GWT是什么&#xff0c;并为GWT设置开发环境。 GWT是一个开源开发工具包&#xff0c;用于开发基于浏览器的复杂Ajax应用程序。 使用GWT&#xff0c;您可以用J…

linux 释放进程res_linux内存查看及释放

查看内存常用的查看内存工具有&#xff1a;top&#xff0c;ps&#xff0c;free&#xff0c;/proc/meminfo&#xff0c;/proc/$PID/status等&#xff0c;一般都指定了虚拟内存占用情况&#xff0c;但ps或/proc/$PID/status中RSS或RSZ指定的是实际内存大小。1)freeroot:~# freeto…

js读取外部json指定字段值完整代码_前端工程化 剖析npm的包管理机制(完整版)...

导读 现如今&#xff0c;前端开发的同学已经离不开 npm 这个包管理工具&#xff0c;其优秀的包版本管理机制承载了整个繁荣发展的NodeJS社区&#xff0c;理解其内部机制非常有利于加深我们对模块开发的理解、各项前端工程化的配置以加快我们排查问题(相信不少同学收到过各种依赖…

计算机专业带给我们的启示,一次电脑网络调查带给我的启示

一次电脑网络调查带给我的启示当今世界&#xff0c;鲜有人不会上网。而许多孩子&#xff0c;也迷上了电脑。就此&#xff0c;我对周围的12个朋友做了调查。其中3人上网玩QQ&#xff0c;8人玩摩尔庄园&#xff0c;仅1人玩单机游戏。很显然&#xff0c;网络已深入孩子们的生活。做…

Apache Derby数据库JVM安全策略

抽象 我已经发布了许多有关Derby的博客&#xff1a; Derby数据库备份 同一主机上的多个Derby网络服务器 Apache Derby数据库用户和权限 与Maven和内存中Derby数据库的集成测试 这本不打算是一个系列。 但是多年来&#xff0c;我越来越多地使用Derby。 我开始使用Derby作为…

大师兄科研网vasp_怎样知道一名研究生有没有科研潜力?

原答案回答在这里了。怎么知道一名研究生有没有科研潜力&#xff1f;​www.zhihu.com大家熟悉的“员工执行力”这个词&#xff0c;其实是个伪命题&#xff0c;因为员工的执行力&#xff1d;领导的领导能力&#xff0c;领导方法得当&#xff0c;每个人都有很强的执行力。那么“学…

西交计算机专业912一样吗,西安交大912(总分404 专业课133分)经验总结

2019年西交912计算机基础经验总结(总分404 政治&#xff1a;68 英语二&#xff1a;84 数学二&#xff1a;119 专业课&#xff1a;133)先说一下个人情况吧。本人2017年毕业于西安电子科技大学计算机科学与技术专业&#xff0c;毕业以后就职于一家国企&#xff0c;奈何不安分&…

分行打印列表python_#python版一行内容分行输出

python版一行内容分行输出 1.[代码][Python]代码236091543 #python版一行内容分行输出 #依山居 18:14 2015/11/4 #题目来源 http://www.bathome.net/thread-1454-1-1.html a="aA1一bB2二cC3三dD4四eE5五fF6六gG7七hH8八iI9九" """ 分行输出为: abcdef…

机箱硬盘指示灯不亮_安钛克DF600 FLUX机箱:FLUX平台第一款机箱,为全民电竞热“降温”...

随着夏天的到来&#xff0c;电脑对散热的要求越来越高&#xff0c;特别是对于希望游戏的电竞玩家&#xff0c;不久前China Joy全球电竞大会的落幕&#xff0c;“全民电竞”这个概念再一次深入人心&#xff0c;而一名电脑主机电竞玩家&#xff0c;势必需要一款散热效果更好的机箱…

java ee maven_针对新手的Java EE7和Maven项目–第7部分

java ee maven从前面的部分恢复 第1 部分 &#xff0c; 第2 部分 &#xff0c; 第3 部分 &#xff0c; 第4 部分 &#xff0c; 第5 部分 &#xff0c; 第6部分 在上一篇文章&#xff08;第6章&#xff09;中&#xff0c;我们发现了如何使用Arquillian和Wildfly 8.1进行JPA2域模…

法在计算机课程中的应用,任务驱动法在计算机办公课程中的应用

摘 要&#xff1a;一体化教学模式中的任务驱动法是建立在建构主义教育理论基础上的一种教学法。笔者结合任务驱动法在Word2010教学中的实施过程&#xff0c;对如何应用任务驱动法展开论述。关键词&#xff1a;任务驱动法 计算机办公课程 具体应用任务驱动法就是在教学过程中&am…

链表node中保存的是什么_Redis源码解析一 --链表结构

Redis源码剖析—链表结构1. redis中的链表在redis中链表的应用非常广泛&#xff0c;例如列表键的底层实现之一就是链表。而且&#xff0c;在redis中的链表结构被实现成为双向链表&#xff0c;因此&#xff0c;在头部和尾部进行的操作就会非常快。通过列表键的命令感受一下双向链…

python数据分析方法和命令_《利用Python进行数据分析》 —— (1)

《利用Python进行数据分析》 —— &#xff08;1&#xff09; Python的学习需要自主探索各种类型&#xff0c;函数和方法的文档。 2.1 Python解释器 在IPython&#xff08;Jupyter Qtconsole)上&#xff0c;可以通过%run命令执行文件中的代码 In [16]: %run hellow.py 1,2,3 10…

JDK 15中的确切绝对整数

JDK 15 Early Access Build b18向Math和StrictMath类引入了新方法&#xff0c;这些方法将在提供的值超出方法所支持的范围时抛出ArithmeticException &#xff0c;而不会发生溢出。 这些方法为Java中的“绝对值”概念带来了Math.addExact &#xff0c; Math.subtractExact和Mat…

浙江金融职业学院计算机一级,浙江金融职业学院全景-360度,720度,高清全景地图-expoon网展...

浙江金融职业学院基本信息&#xff1a;院校类型&#xff1a;财经类所在地&#xff1a;浙江学历层次&#xff1a;专科招办电话&#xff1a;0571-86739200、86739000、86739100电子邮箱 : zjfczs2008126.com通讯地址 : 浙江杭州市下沙高教园区东区学源街118号学校简介&#xff1a…

用python找对象_还在单身的你 Python教你如何脱单

程序员有女朋友&#xff1f;new一个就行。Python只要内存够&#xff0c;想new多少个对象都不是问题。由于行业环境的原因&#xff0c;程序员单身的确实多&#xff0c;这也是程序员的世纪难题。今天&#xff0c;不是给大家发对象&#xff0c;只教大家方法。今天教大家怎么用Pyth…

系统页面升级系统中_中交出行通勤班线系统全新升级!页面亮点功能说明

最近&#xff0c;中交出行上线了全新版本的通勤班线系统&#xff0c;乘客端定制班线首页及购票流程界面全新改版&#xff0c;车企后台也做了优化。一起来看看有哪些亮点吧&#xff01;首页、搜索结果页等&#xff0c;已绑定微信的老用户&#xff0c;无感知的自动登录。通勤班线…