• 【JUC】交换器Exchanger详解


     

    前言

    JDK中提供了不少的同步工具,现在分享一个相对比较冷门的同步工具——交换器(Exchanger)。你知道Exchanger的作用是什么吗?实现机制是什么?可以用来做什么呢?

    Exchanger介绍

    交换器(Exchanger),顾名思义,用于两个线程之间进行数据交换的。

    简单来说,就是一个线程在完成一定的事务后想与另一个线程交换数据,则第一个先拿出数据的线程会一直等待第二个线程,直到第二个线程拿着数据到来时才能彼此交换对应数据。如下图所示:

    两个线程通过 exchange() 方法交换数据,如果第一个线程先执行 exchange() 方法,它会一直等待第二个线程也执行 exchange 方法,当两个线程都到达同步点时,这两个线程就可以交换数据

    API介绍

    构造方法

    • Exchanger():创建一个交换器

    常用方法

    • V exchange(V x): 交换数据,如果只有一个线程,会阻塞,直到另外一个线程也调用exchange, 支持中断
    • V exchange(V x, long timeout, TimeUnit unit): 带超时参数的交换数据

    Exchanger使用

    这不,马上圣诞节要到了,你要和你对象交换礼物,不准备的话,你就要死的很惨~~我们就可以用Exchanger来实现。

    1. @Slf4j(topic = "c.ExchangerTest")
    2. public class ExchangerTest {
    3. public static void main(String[] args) throws InterruptedException {
    4. Exchanger<String> exchanger = new Exchanger<>();
    5. Thread boy = new Thread(new Runnable() {
    6. @Override
    7. public void run() {
    8. log.info("你开始准备礼物~~~~~~~~~~~~");
    9. try {
    10. // 模拟准备礼物时间
    11. Thread.sleep(5000);
    12. String gift = "IPhone 14";
    13. log.info("你送了礼物: {}", gift);
    14. String recGift = exchanger.exchange(gift);
    15. log.info("你收到了礼物: {}", recGift);
    16. } catch (InterruptedException e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. });
    21. Thread girl = new Thread(new Runnable() {
    22. @Override
    23. public void run() {
    24. log.info("女朋友开始准备礼物~~~~~~~~~~~~");
    25. try {
    26. // 模拟准备礼物时间
    27. Thread.sleep(6000);
    28. String gift = "一个吻";
    29. log.info("女朋友送了礼物: {}", gift);
    30. String recGift = exchanger.exchange(gift);
    31. log.info("女朋友收到了礼物: {}", recGift);
    32. } catch (InterruptedException e) {
    33. e.printStackTrace();
    34. }
    35. }
    36. });
    37. boy.start();
    38. girl.start();
    39. boy.join();
    40. girl.join();
    41. }
    42. }
    43. 复制代码

    运行结果:

    • 中间阻塞等待了一秒,直到你女朋友也准备好了礼物。

    实现机制

    实现机制也很容易能够想到,Exchanger类中定义一个槽位slot,

    1. A线程交换数据时,发现slot为空,则将需要交换的数据放在slot中, 阻塞当前线程,等待其它线程进来交换数据
    2. 等线程B进来,读取A设置的数据,然后设置线程B需要交换的数据,然后唤醒A线程。

    Exchanger的源码实现大家感兴趣的话,自己可以看看。

    总结

    本文讲解了交换器Exchanger,是jdk5中引入的一个同步器。实际上在平时工作场景中基本上很少应用,按照官方注释说可以应用在基因算法或者管道设计,太抽象了,大家就当扩扩知识面吧。

  • 相关阅读:
    【docker专栏6】详解docker容器状态转换管理命令
    摩根士丹利选出10家公司参加其多元文化创新实验室的首个全球班
    2021年下半年信息安全工程师下午真题及答案解析
    SSH命令详解
    数据结构学习笔记(Ⅷ):排序
    大浪淘沙,自动驾驶迎来下半场
    Flutter布局组件:水平/垂直组件、叠加布局组件、流式布局组件
    【C/C++笔试练习】继承和派生的概念、虚函数的概念、派生类的析构函数、纯虚函数的概念、动态编译、多态的实现、参数解析、跳石板
    Spring 如何实现一个CGLlB动态代理呢?
    使用vs查看虚函数内存分布
  • 原文地址:https://blog.csdn.net/BASK2311/article/details/128143887