如果两个线程在运行过程中需要交换彼此的信息,比如一个数据或者使用的空间,就需要用到 Exchanger 这个类,Exchanger 为线程交换信息提供了非常方便的途径,它可以作为两个线程交换对象的同步点,只有当每个线程都在进入 exchange() 方法并给出对象时,才能接受其他线程返回时给出的对象。

每次只能两个线程交换数据,如果有多个线程,也只有两个能交换数据。下面看个通俗的例子:一手交钱一首交货!

  1. public class ExchangerTest {

  2.    public static void main(String[] args) {

  3.        ExecutorService service = Executors.newCachedThreadPool();

  4.        final Exchanger exchanger = new Exchanger(); //定义一个交换对象,用来交换数据      

  5.        //开启一个线程执行任务

  6.        service.execute(new Runnable(){            

  7.            @Override

  8.            public void run() {

  9.                try {                

  10.                    String data1 = "海洛因";

  11.                    System.out.println("线程" + Thread.currentThread().getName()

  12.                            + "正在把毒品" + data1 + "拿出来");                    

  13.                    Thread.sleep((long)(Math.random()*10000));

  14.                  //把要交换的数据传到exchange方法中,然后被阻塞,等待另一个线程与之交换。返回交换后的数据

  15.                    String data2 = (String)exchanger.exchange(data1);

  16.                    System.out.println("线程" + Thread.currentThread().getName() +  

  17.                    "用海洛因换来了" + data2);

  18.                }catch(Exception e){    

  19.                } finally {

  20.                    service.shutdown();

  21.                    System.out.println("交易完毕,拿着钱快跑!");

  22.                }

  23.            }    

  24.        });

  25.        //开启另一个线程执行任务

  26.        service.execute(new Runnable(){            

  27.            @Override

  28.            public void run() {

  29.                try {                

  30.                    String data1 = "300万";

  31.                    System.out.println("线程" + Thread.currentThread().getName() +  

  32.                    "正在把" + data1 +"拿出来");

  33.                    Thread.sleep((long)(Math.random()*10000));                      

  34.                    String data2 = (String)exchanger.exchange(data1);                    

  35.                    System.out.println("线程" + Thread.currentThread().getName() +  

  36.                    "用300万弄到了" + data2);

  37.                }catch(Exception e){    

  38.                } finally {

  39.                    service.shutdown();

  40.                    System.out.println("交易完毕,拿着海洛因快跑!");

  41.                }

  42.            }    

  43.        });        

  44.    }

  45. }

从代码中我仿佛看到了两个人在交易毒品的场面……来看一下交易结果如何:

线程pool-1-thread-1正在把毒品海洛因拿出来
线程pool-1-thread-2正在把300万拿出来
线程pool-1-thread-2用300万弄到了海洛因
线程pool-1-thread-1用海洛因换来了300万
交易完毕,拿着海洛因快跑!
交易完毕,拿着钱快跑!

跑的倒是快,从运行结果来看,确实实现了数据的交换,这个只是交换一个基本类型的数据而已,它真正的用处不仅仅局限于此,比如我们可以交换一个对象,这就有用了,JDK 官方提到了一个高级的应用:

使用 Exchanger 在线程间交换缓冲区,因此,在需要时,填充缓冲区的线程获取一个新腾空的缓冲区,并将填满的缓冲区传递给腾空缓冲区的线程。

这就得根据实际情况了,思想和上面的一样,实际中肯定要定义一个缓冲区的类,然后两个线程之间交换的就是这个缓冲区的类即可,至于类中如何实现,就得看实际情况了。Exchanger 的使用就总结这么多吧~

如果两个线程在运行过程中需要交换彼此的信息,比如一个数据或者使用的空间,就需要用到 Exchanger 这个类,Exchanger 为线程交换信息提供了非常方便的途径,它可以作为两个线程交换对象的同步点,只有当每个线程都在进入 exchange() 方法并给出对象时,才能接受其他线程返回时给出的对象。

每次只能两个线程交换数据,如果有多个线程,也只有两个能交换数据。下面看个通俗的例子:一手交钱一首交货!

  1. public class ExchangerTest {

  2.    public static void main(String[] args) {

  3.        ExecutorService service = Executors.newCachedThreadPool();

  4.        final Exchanger exchanger = new Exchanger(); //定义一个交换对象,用来交换数据      

  5.        //开启一个线程执行任务

  6.        service.execute(new Runnable(){            

  7.            @Override

  8.            public void run() {

  9.                try {                

  10.                    String data1 = "海洛因";

  11.                    System.out.println("线程" + Thread.currentThread().getName()

  12.                            + "正在把毒品" + data1 + "拿出来");                    

  13.                    Thread.sleep((long)(Math.random()*10000));

  14.                  //把要交换的数据传到exchange方法中,然后被阻塞,等待另一个线程与之交换。返回交换后的数据

  15.                    String data2 = (String)exchanger.exchange(data1);

  16.                    System.out.println("线程" + Thread.currentThread().getName() +  

  17.                    "用海洛因换来了" + data2);

  18.                }catch(Exception e){    

  19.                } finally {

  20.                    service.shutdown();

  21.                    System.out.println("交易完毕,拿着钱快跑!");

  22.                }

  23.            }    

  24.        });

  25.        //开启另一个线程执行任务

  26.        service.execute(new Runnable(){            

  27.            @Override

  28.            public void run() {

  29.                try {                

  30.                    String data1 = "300万";

  31.                    System.out.println("线程" + Thread.currentThread().getName() +  

  32.                    "正在把" + data1 +"拿出来");

  33.                    Thread.sleep((long)(Math.random()*10000));                      

  34.                    String data2 = (String)exchanger.exchange(data1);                    

  35.                    System.out.println("线程" + Thread.currentThread().getName() +  

  36.                    "用300万弄到了" + data2);

  37.                }catch(Exception e){    

  38.                } finally {

  39.                    service.shutdown();

  40.                    System.out.println("交易完毕,拿着海洛因快跑!");

  41.                }

  42.            }    

  43.        });        

  44.    }

  45. }

从代码中我仿佛看到了两个人在交易毒品的场面……来看一下交易结果如何:

线程pool-1-thread-1正在把毒品海洛因拿出来
线程pool-1-thread-2正在把300万拿出来
线程pool-1-thread-2用300万弄到了海洛因
线程pool-1-thread-1用海洛因换来了300万
交易完毕,拿着海洛因快跑!
交易完毕,拿着钱快跑!

跑的倒是快,从运行结果来看,确实实现了数据的交换,这个只是交换一个基本类型的数据而已,它真正的用处不仅仅局限于此,比如我们可以交换一个对象,这就有用了,JDK 官方提到了一个高级的应用:

使用 Exchanger 在线程间交换缓冲区,因此,在需要时,填充缓冲区的线程获取一个新腾空的缓冲区,并将填满的缓冲区传递给腾空缓冲区的线程。

这就得根据实际情况了,思想和上面的一样,实际中肯定要定义一个缓冲区的类,然后两个线程之间交换的就是这个缓冲区的类即可,至于类中如何实现,就得看实际情况了。Exchanger 的使用就总结这么多吧~

作者:华为云云享专家倪升武

【并发技术16】线程同步工具Exchanger的使用相关推荐

  1. java线程并发库之--线程同步工具Exchanger的使用

    Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据.今天我们就通过实例来学习一下Exchanger的用法. Exchanger的简单实例 Exchanger是 ...

  2. java线程并发库之--线程同步工具CountDownLatch用法

    CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 主要方法 public CountDownLatch(int count); pu ...

  3. (三)线程同步工具集_1---控制线程并发访问一个资源

    2019独角兽企业重金招聘Python工程师标准>>> 线程同步工具集 在前面了解了线程的同步机制,临界区等,了解了线程的两种基本的同步机制: synchronized关键字: Lo ...

  4. 线程同步工具(七)在并发任务间交换数据

    声明:本文是< Java 7 Concurrency Cookbook >的第三章, 作者: Javier Fernández González 译者:郑玉婷 在并发任务间交换数据 Jav ...

  5. 同步工具——Exchanger

    一.Exchanger简介 Exchanger--交换器,是JDK1.5时引入的一个同步器,从字面上就可以看出,这个类的主要作用是交换数据. Exchanger有点类似于CyclicBarrier,我 ...

  6. Java核心(三)并发中的线程同步与锁

    2019独角兽企业重金招聘Python工程师标准>>> 乐观锁.悲观锁.公平锁.自旋锁.偏向锁.轻量级锁.重量级锁.锁膨胀...难理解?不存的!来,话不多说,带你飙车. 上一篇介绍了 ...

  7. JAVA并发编程3_线程同步之synchronized关键字

    在上一篇博客里讲解了JAVA的线程的内存模型,见:JAVA并发编程2_线程安全&内存模型,接着上一篇提到的问题解决多线程共享资源的情况下的线程安全问题. 不安全线程分析 public clas ...

  8. 对Java多线程编程的初步了解,实现多线程的三种方式以及多线程并发安全的线程同步机制

    什么叫进程?什么叫线程? 进程相当于一个应用程序,线程就是进程中的一个应用场景或者说是一个执行单元,一个进程可以启动多个线程,每个线程执行不同的任务,一个线程不能单独存在,他必须是进程的一部分,当进程 ...

  9. (三)线程同步工具集_2---控制并发访问资源的多个副本

    2019独角兽企业重金招聘Python工程师标准>>> 控制并发访问资源的多个副本 在前面的记录中使用binary semaphore实现了一个例子,这个例子是用来保护一个共享资源: ...

最新文章

  1. SQL命令执行数据库备份
  2. [转帖]SAP初级学习者一句话入门06—PS
  3. 1台电脑,3个月,没有任何数据支撑!我做出了行业一线标准的识别应用
  4. java SSM多操作注解回滚
  5. Python Dict用法
  6. 阿里巴巴创新研究计划AIR2018正式发布 邀全球学者共创未来
  7. IIS7.5配置对PHP的支持
  8. Tomcat根据JSP生成Servlet机制解析
  9. 算法笔记--字符串hash
  10. TensorFlow 加载多个模型的方法
  11. 想对你说的话,就在这里!
  12. c调python_应该是史上最全的python调用C接口
  13. cocos2dX之一——安卓环境搭建
  14. Android 11正式发布:小米、OPPO等手机将陆续更新
  15. 2021-09-1311. 盛最多水的容器 数组 双指针
  16. 【VB6】如何用纯VB代码写个五子棋程序?(一)
  17. python自学篇——PyGame模块的所有功能函数详解
  18. php 人物换装原理,装备库解析——换装机制,宝石选择原理
  19. 深度长文:Power Automation 帮助企业实现数字化转型
  20. 一作3篇SCI认定A类博士!享100万安家费+30万科启!三年副教授待遇+2K/月津贴!...

热门文章

  1. pcb板可挖孔吗_PCB板微孔加工方法之机械钻孔
  2. 黑龙江工程学院计算机系有几个门,黑龙江工程学院本科专业设置一览表
  3. mysql 导入dmp_mysql导入导出sql文件
  4. 443显示正常服务器错误,wordpress 出现443 NOT FOUND-apache错误的解决方案
  5. macos 编译php,TODO:macOS编译PHP7.1
  6. sql查询月天数之和,函数相加
  7. 洛谷T1967 货车运输 Kruskal最大生成树倍增LCA
  8. JavaScript中的parseInt和Number函数
  9. RTT时钟管理篇——阻塞延时和时基更新函数
  10. linux磁珠技术,MACS磁珠分选技术基本原理(图文释义)