【JUC】交换器Exchanger详解

简介: 【JUC】交换器Exchanger详解

前言


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


Exchanger介绍


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

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


1671202277083.jpg


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


API介绍


构造方法

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

常用方法

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


Exchanger使用


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

@Slf4j(topic = "c.ExchangerTest")
public class ExchangerTest {
    public static void main(String[] args) throws InterruptedException {
        Exchanger<String> exchanger = new Exchanger<>();
        Thread boy = new Thread(new Runnable() {
            @Override
            public void run() {
                log.info("你开始准备礼物~~~~~~~~~~~~");
                try {
                    // 模拟准备礼物时间
                    Thread.sleep(5000);
                    String gift = "IPhone 14";
                    log.info("你送了礼物: {}",  gift);
                    String recGift = exchanger.exchange(gift);
                    log.info("你收到了礼物: {}",  recGift);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread girl = new Thread(new Runnable() {
            @Override
            public void run() {
                log.info("女朋友开始准备礼物~~~~~~~~~~~~");
                try {
                    // 模拟准备礼物时间
                    Thread.sleep(6000);
                    String gift = "一个吻";
                    log.info("女朋友送了礼物: {}",  gift);
                    String recGift = exchanger.exchange(gift);
                    log.info("女朋友收到了礼物: {}",  recGift);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        boy.start();
        girl.start();
        boy.join();
        girl.join();
    }
}

运行结果:


1671202299601.jpg


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


实现机制


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

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

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


总结


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

目录
相关文章
|
资源调度
JUC并发编程之同步器(Semaphore、CountDownLatch、CyclicBarrier、Exchanger、CompletableFuture)附带相关面试题
1.Semaphore(资源调度) 2.CountDownLatch(子线程优先) 3.CyclicBarrier(栅栏) 4.Exchanger(公共交换区) 5.CompletableFuture(异步编程)
179 0
|
算法 安全 Java
【阻塞队列BlockingQueue&非阻塞队列ConcurrentLinkedQueue&同步队列SyncQueue】
【阻塞队列BlockingQueue&非阻塞队列ConcurrentLinkedQueue&同步队列SyncQueue】
|
7月前
|
Java
JUC 常用 4 大并发工具类 CountDownLatch、CyclicBarrier、Semaphore、ExChanger
JUC 常用 4 大并发工具类 CountDownLatch、CyclicBarrier、Semaphore、ExChanger
|
7月前
学习多线程之Exchanger使用
学习多线程之Exchanger使用
36 0
|
Java 双11
Semaphore和Exchanger
Semaphore和Exchanger
|
存储 缓存 安全
JUC之阻塞队列解读(BlockingQueue)
JUC之阻塞队列解读(BlockingQueue)
|
缓存 安全 Java
JUC系列学习(四):线程池阻塞队列BlockingQueue及其相关实现ArrayBlockingQueue、LinkedBlockingQueue
线程池阻塞队列BlockingQueue及其相关实现ArrayBlockingQueue、LinkedBlockingQueue
117 0
|
存储 缓存
并发编程之BlockingQueue队列
BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种:
227 0
【JAVA并发编程专题】Exchanger的理解和使用
【JAVA并发编程专题】Exchanger的理解和使用