• 【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中引入的一个同步器。实际上在平时工作场景中基本上很少应用,按照官方注释说可以应用在基因算法或者管道设计,太抽象了,大家就当扩扩知识面吧。

  • 相关阅读:
    Kubernetes开放接口:CRI、CNI、CSI
    Selenium4+Python3系列(七) - Iframe、Select控件、交互式弹出框、执行JS、Cookie操作
    Java安全—CommonsCollections7
    第03章 Tableau基础操作
    JavaScript中获取数组中的元素数量及去重
    java-net-php-python-ssm电影推荐网站计算机毕业设计程序
    Linux笔记之diff和vimdiff
    flink源码编译-job提交
    redis报错 Error getaddrinfo ENOTFOUND
    Docker kill 1无效
  • 原文地址:https://blog.csdn.net/BASK2311/article/details/128143887