使用 Redisson 实现分布式 CountDownLatch,如何使用RCountDownLatch实现内外网数据互通的超时控制?

闭锁(CountDownLatch)是一种用于同步多个线程的机制,它可以让一个或多个线程等待其他线程完成某个任务后再继续执行。

在Java中,RCountDownLatch 是 Redisson 提供的分布式闭锁实现,它基于 Redis 的分布式系统,可以在分布式环境中实现多个线程的同步。

闭锁的核心概念是一个计数器,该计数器可以被初始化为一个正整数,并通过 trySetCount() 方法来设置初始计数值。每个线程在完成任务后,可以通过 countDown() 方法将计数器减一。当计数器的值达到零时,所有等待的线程将被释放,继续执行后续操作。

RCountDownLatch latch = redissonClient.getCountDownLatch(LATCH_KEY);
latch.trySetCount(1);
latch.await();// 在其他线程或JVM里
RCountDownLatch latch = redissonClient.getCountDownLatch(LATCH_KEY);
latch.countDown();

1、实现多个线程的同步

下面是一个示例代码,演示了如何使用 RCountDownLatch 实现多个线程的同步:

import org.redisson.Redisson;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class CountDownLatchExample {private static final int THREAD_COUNT = 5;public static void main(String[] args) throws InterruptedException {// 初始化 Redisson 客户端RedissonClient redissonClient = getRedissonClient();// 创建闭锁对象,设置初始计数值RCountDownLatch latch = redissonClient.getCountDownLatch("my-latch");latch.trySetCount(THREAD_COUNT);// 创建多个线程并启动for (int i = 0; i < THREAD_COUNT; i++) {new Thread(() -> {// 模拟线程执行任务// ...// 任务完成后,计数器减一latch.countDown();}).start();}// 等待所有线程任务完成latch.await();// 所有线程任务完成后,执行后续操作System.out.println("All threads have completed!");// 关闭 Redisson 客户端redissonClient.shutdown();}private static RedissonClient getRedissonClient() {Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");return Redisson.create(config);}
}

解析:

  1. 首先,我们通过调用 getRedissonClient() 方法初始化了 Redisson 客户端。
  2. 接下来,我们通过 redissonClient.getCountDownLatch(LATCH_KEY) 创建了一个 RCountDownLatch 对象,并将其与指定的键 LATCH_KEY 关联起来。
  3. 使用 latch.trySetCount(1) 方法设置了初始计数值为1。
  4. 然后,我们调用 latch.await() 方法来等待其他线程完成任务。如果计数器的值不为0,当前线程将被阻塞。
  5. 当其他线程完成任务后,调用 latch.countDown() 方法将计数器减一。
  6. 最后,我们关闭了 Redisson 客户端。

总结:
本文介绍了如何使用 Redisson 实现分布式的 CountDownLatch。通过初始化 Redisson 客户端、创建 RCountDownLatch 对象、设置初始计数值、等待其他线程完成任务和计数减一等步骤,我们可以在分布式环境下进行线程同步操作。

2、经典场景

【需求】:我有一个外网接口,但是它无法直接访问内网的数据。现在有一个第三方需要通过外网接口获取内网的数据。我希望在第三方请求外网接口时,外网接口能够等待内网获取数据并返回给第三方,如果等待超过30秒则直接返回超时。

为了满足这个需求,我们可以使用 RCountDownLatch 来设计实现。具体的设计方案如下:

  1. 第三方向外网接口发送请求。
  2. 外网接口接收到请求后,将请求信息发送到 Kafka。
  3. 内网的服务启动一个消费者,从 Kafka 中获取请求信息。
  4. 内网服务根据请求内容获取数据,并将数据存放在 Redis 中。
  5. 内网服务使用 RCountDownLatch 创建一个闭锁对象,并设置初始计数值为 1。
  6. 内网服务在获取并存放数据到 Redis 后,调用 countDown() 方法将闭锁计数器减一。
  7. 外网接口使用 await() 方法等待闭锁计数器达到零,即等待内网服务完成数据的获取和存放到 Redis。
  8. 当闭锁计数器达到零时,外网接口从 Redis 中获取数据,并将数据作为响应返回给第三方。
  9. 如果等待超过30秒,外网接口直接返回超时信息给第三方。

通过这个设计方案,外网接口可以等待内网服务完成数据获取并返回给第三方。 RCountDownLatch 在这里起到了同步的作用,确保外网接口在获取到数据之前能够等待。

这个设计方案中,RCountDownLatch 用于外网服务等待内网服务完成数据获取和存放到 Redis 的过程。以下是一个简单的示例代码:

import org.redisson.api.RCountDownLatch;
import org.redisson.api.RedissonClient;@Service
@RequiredArgsConstructor
public class OuterServiceImpl implements OuterService {/*** RedissonClient */private final RedissonClient redissonClient;/*** KafkaConsumer */private final KafkaConsumer kafkaConsumer;public Response processRequest(Request request) {// 发送请求到 KafkakafkaProducer.send(request);// 创建闭锁对象并设置初始计数值为 1【】每个请求或会话都需要有自己唯一的 LATCH_KEYRCountDownLatch latch = redissonClient.getCountDownLatch(LATCH_KEY);latch.trySetCount(1);try {// 等待内网服务完成数据获取和存放到 Redisif (!latch.await(30, TimeUnit.SECONDS)) {// 超时处理return new Response("Timeout");}// 从 Redis 中获取数据Object data = redissonClient.getBucket(request.getId()).get();// 返回数据给第三方return new Response("Success", data);} catch (InterruptedException e) {Thread.currentThread().interrupt();// 异常处理return new Response("Error");}}// Kafka 消费者监听处理请求private void handleRequest(Message message) {// 处理请求并将数据存放到 Redis// 计数器减一RCountDownLatch latch = redissonClient.getCountDownLatch(LATCH_KEY);latch.countDown();}
}

在上述示例代码中,OuterService 类是一个外网服务,它使用 RCountDownLatch 实现了等待内网服务完成数据获取和存放到 Redis 的功能。在 processRequest() 方法中,它发送请求到 Kafka,并创建了一个闭锁对象。然后等待闭锁计数器达到零,即等待内网服务完成数据获取和存放到 Redis。如果等待时间超过 30 秒,将返回超时信息给第三方。

handleRequest() 方法中,外网服务的 Kafka 消费者监听处理请求,并在处理完成后调用 countDown() 方法,将闭锁计数器减一。

需要注意的是,示例代码中的 Kafka 消费者和生产者等细节并未展示,你需要根据实际情况进行实现。

总结:通过使用 RCountDownLatch,我们可以实现外网接口等待内网获取数据的场景。外网服务在调用内网服务之后等待闭锁计数器达到零,然后从 Redis 中获取数据返回给第三方。如果等待时间超过指定时间,则直接返回超时信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/754460.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Spring Boot的研究生志愿填报辅助系统

摘 要 二十一世纪我们的社会进入了信息时代&#xff0c;信息管理系统的建立&#xff0c;大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多&#xff0c;而在线管理系统刚好能满足这些需求&#xff0c;在线管理系统突破了传统管理方式的局限性。于是本文针对这一…

掌握请求控制权:Axios 如何取消请求的两种方法

在前端开发中&#xff0c;网络请求是非常常见的操作。而有时候&#xff0c;我们可能需要在发送请求后取消它&#xff0c;比如用户在请求还未完成时离开了当前页面或者执行了其他操作&#xff0c;本文将介绍如何在使用 Axios 发送请求时取消这些请求。 基本概念 在 Axios 中&am…

【NLP03-新闻主题分类任务】

新闻主题分类任务 背景 以一段新闻报道中的文本描述内容为输入&#xff0c;使用模型帮助我们判断它最优可能属于哪一种类型的新闻&#xff0c;这是典型的文本分类问题&#xff0c;这里假定每种类型是互斥的&#xff0c;即文本描述有且只有一种类型 新闻主题分类数据 #通过t…

swagger使用手册

1.导入依赖 <!--引入swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.7.0</version></dependency><dependency><groupId>io.springfox</…

什么是集成学习

集成学习是一种机器学习方法&#xff0c;目的是将多个基本学习算法组合起来&#xff0c;以达到更好的预测性能。通过将多个模型的预测结果进行加权平均或投票&#xff0c;集成学习能够减少单个模型的偏差和方差&#xff0c;从而提高整体的泛化能力。常见的集成学习方法包括Bagg…

AR/MR产品设计(二):如何用一双手完成与虚拟对象的自然交互

AR/MR产品设计&#xff08;二&#xff09;&#xff1a;如何用一双手完成与虚拟对象的自然交互 - 知乎 手是我们与现实世界交互最重要的方式&#xff0c;同样在虚实混合的世界中是最重要的交互方式 在AR/MR/VR的交互中&#xff0c;手势交互会作为XR的重要交互动作&#xff0c;因…

鸿蒙开发 一 (一)、框架了解

一、UI框架 开发范式名称 语言生态 UI更新方式 适用场景 适用人群 声明式开发范式 ArkTS语言 数据驱动更新 复杂度较大、团队合作度较高的程序 移动系统应用开发人员、系统应用开发人员 类Web开发范式 JS语言 数据驱动更新 界面较为简单的程序应用和卡片 Web前端…

视频技术1:使用ABLMediaServer推流rtsp

ABLMediaServer定位是高性能、高稳定、开箱即用、商用级别的流媒体服务器 下边展示了如何把1个mp3作为输入源&#xff0c;转换为rtsp流的过程。 作用&#xff1a;用rtsp模拟摄像头的视频流 1、启动ABLMediaServer ABLMediaServer-2024-03-13\WinX64\ABLMediaServer.exe 配…

聚类分析 | Matlab实现基于NNMF+DBO+K-Medoids的数据聚类可视化

聚类分析 | Matlab实现基于NNMFDBOK-Medoids的数据聚类可视化 目录 聚类分析 | Matlab实现基于NNMFDBOK-Medoids的数据聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 NNMFDBOK-Medoids聚类&#xff0c;蜣螂优化算法DBO优化K-Medoids 非负矩阵分解&#xff08…

简单来说依赖注入 Unity (c#)

在游戏开发领域,构建引人入胜且组织良好的游戏是最终目标。然而,随着项目复杂性的增加,管理依赖关系和确保代码灵活性可能成为一项艰巨的任务。这就是依赖注入 (DI) 发挥作用的地方。 在本文中,我们将深入 Unity 中的依赖注入世界,探索其概念、优点和实际实现。最后,你将…

代码随想录算法训练营第14天 part02 | 二叉树的递归遍历

递归三要素 确定递归函数的参数和返回值&#xff1a; 确定哪些参数是递归的过程中需要处理的&#xff0c;那么就在递归函数里加上这个参数&#xff0c; 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。 确定终止条件&#xff1a; 写完了递归算法, 运行的时候…

信息学奥赛一本通之MAC端VSCode C++环境配置

前提 安装 Visual Studio CodeVSCode 中安装 C/C扩展确保 Clang 已经安装&#xff08;在终端中输入命令&#xff1a;clang --version 来确认是否安装&#xff09;未安装&#xff0c;在命令行执行xcode-select --install 命令&#xff0c;会自行安装&#xff0c;安装文件有点大…

【Hadoop】解决Hive创建内部表失败:正确配置事务管理器

谁让你我静似月 只能在心里默念 檐下燕替我飞到你身边 谁让你我静似月 各自孤单错弄弦 风吹的帘落见月人不眠 &#x1f3b5; 周笔畅《谁动了我的琴弦》 在使用Apache Hive进行数据处理时&#xff0c;创建内部表是一项常见的操作&#xff0c;它允许用户在H…

STM32实验DMA数据搬运小助手

本次实验做的是将一个数组的内容利用DMA数据搬运小助手搬运到另外一个数组中去。 最后的实验结果&#xff1a; 可以看到第四行的数据就都不是0了&#xff0c;成功搬运了过来。 DMA实现搬运的步骤其实不是很复杂&#xff0c;复杂的是结构体参数&#xff1a; 整个步骤为&#xf…

【Auto-GPT】windows搭建记录

AutoGPT 是基于 ChatGPT 的文本 AI 助手&#xff0c;在 ChatGPT 的基础上做了增强&#xff0c;用户在终端输入指令后&#xff0c;AutoGPT 可以根据最终的目标&#xff0c;不断生成任务及提示语交给 ChatGPT 处理&#xff0c;然后一步又一步的接近正确答案&#xff0c;在得到最终…

面试经典150题 -- 分治 (总结)

总的链接 : 面试经典 150 题 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 108 . 将有序数组转换成二叉搜索树 : 链接 : . - 力扣&#xff08;LeetCode&#xff09; 思路 : 选择中间位置左边的数字作为根节点&#xff0c;然后递归调…

Flutter如何正确使用图片资源

现况 在使用Flutter中Image控件加载本地图片时&#xff0c;我们一般使用如下&#xff1a; // 图片资源放在"assets/images"目录下. Image.asset("assets/images/muma.png"),那么问题就来了&#xff0c;这样使用可能会出现一些问题。 问题1&#xff1a;如…

PostgreSQL 锁机制

锁存在的意义 在了解 PostgreSQL 锁之前&#xff0c;我们需要了解锁存在的意义是啥&#xff1f; 当多个会话同时访问数据库的同一数据时&#xff0c;理想状态是为所有会话提供高效的访问&#xff0c;同时还要维护严格的数据一致性。那数据一致性通过什么来维护呢&#xff0c;…

深入浅出Go的`encoding/xml`库:实战开发指南

深入浅出Go的encoding/xml库&#xff1a;实战开发指南 引言基本概念XML简介Go语言中的XML处理结构体标签&#xff08;Struct Tags&#xff09; 解析XML数据使用xml.Unmarshal解析XML结构体标签详解处理常见解析问题 生成XML数据使用xml.Marshal生成XML使用xml.MarshalIndent优化…

加速量子计算机商业化!富士通日立NEC等联合成立新量子计算公司

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨王珩 编译/排版丨沛贤 深度好文&#xff1a;700字丨5分钟阅读 日本工业界和学术界将在 2024 年联合成立新一家公司&#xff0c;研发量子计算机并将其商业化。包括富士通、日立和NEC在内…