首页 > 其他分享 >【JUC】交换器Exchanger详解

【JUC】交换器Exchanger详解

时间:2022-12-02 11:34:02浏览次数:70  
标签:交换器 exchange JUC 交换 线程 Exchanger 礼物

欢迎关注专栏【JAVA并发】

前言

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来实现。

@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();

}
}

运行结果:

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

实现机制

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

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

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

总结

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

如果本文对你有帮助的话,请留下一个赞吧

标签:交换器,exchange,JUC,交换,线程,Exchanger,礼物
From: https://www.cnblogs.com/alvinscript/p/16943922.html

相关文章

  • 【JUC】循环屏障CyclicBarrier详解
    欢迎关注专栏【JAVA并发】前言jdk中提供了许多的并发工具类,大家可能比较熟悉的有CountDownLatch,主要用来阻塞一个线程运行,直到其他线程运行完毕。而jdk还有一个功能类......
  • JUC源码学习笔记6——ReentrantReadWriteLock
    系列文章目录和关于我阅读此文需要有AQS独占和AQS共享的源码功底,推荐阅读:1.JUC源码学习笔记1——AQS独占模式和ReentrantLock2.JUC源码学习笔记2——AQS共享和Semaphore......
  • 【JUC】信号量Semaphore详解
    欢迎关注专栏【JAVA并发】欢迎关注个人公众号——JAVA旭阳前言大家应该都用过synchronized关键字加锁,用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允......
  • JUC
    JUC概述JUC简介在Java中,线程部分是一个重点,本篇文章说的JUC也是关于线程的。JUC就是java.util.concurrent工具包的简称。这是一个处理线程的包,JDK1.5开始出现的。进程......
  • JUC并发编程
    线程和进程进程:一个程序一个进程往往可以包含多个线程,至少包含一个线程:对于java而言:Thread,Runnable,Callablejava不可以开启线程并发(多个线程操作同一个资源)CPU一......
  • JUC并发编程(2)
    cpu密集型:几核就设置几,可以保持cpu的效率最高io密集型:设置大于判断你程序中十分耗io资源的线程ForkJoin:分而治之和工作窃取算法Future:异步回调:比如我i请求阻塞线程两秒......
  • JUC学习笔记——并发工具线程池
    JUC学习笔记——并发工具线程池在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的并发工具线程池我们会分为以下几部分进行介绍:线程池介绍自定义线程池模......
  • JUC并发编程
    1并发:多个线程操作同一个资源在cou一核的时候,多个线程模拟并发2并行cpu多核的时候,多个线程同时执行3并发编程的本质:充分利用cpu的资源4wait和sleep的区别:wait来自o......
  • nunjucks模板语法
    循环语句server.jsconstKoa=require("koa");//引入koa构造函数constapp=newKoa();//创建应用constviews=require("koa-views");//引入koa-viewsconstnunju......
  • Nunjucks模板入门
    概述安装nunjucks代码实现server.jsconstKoa=require("koa");//引入koa构造函数constapp=newKoa();//创建应用constviews=require("koa-views");//引入k......