redis全局唯一ID生成策略、countDownLatch、Lambda表达式总结

redis全局唯一ID生成策略

  • 一、有哪些生成全局唯一ID的策略
  • 二、使用Redis自增
    • 1. 分析
    • 2. RedisIdWorker配置类
    • 3 单元测试+注解分析(难点较多)
      • 3.1 countDownLatch前言
      • 3.2 常用方法

一、有哪些生成全局唯一ID的策略

在这里插入图片描述

二、使用Redis自增

1. 分析

在这里插入图片描述

2. RedisIdWorker配置类

主要的逻辑就是,生成一个long类型的id,然后前31位通过时间戳来填充,后32位通过自增来填充,前31位用来判断时间,后32位是为了防止在那一秒中的时候,有成千上万的订单。

@Component
public class RedisIdWorker {private static final long BEGIN_TIMESTAMP=1689811200;/*** 序列号的位数*/private static final int COUNT_BITS=32;private StringRedisTemplate  stringRedisTemplate;public RedisIdWorker(StringRedisTemplate stringRedisTemplate){//可以使用构造函数来注入,也可以直接用    @Resourcethis.stringRedisTemplate=stringRedisTemplate;}public long nextId(String keyPrefix){//这个传入的是别名,就是用于区别缓存名//1.生成时间戳LocalDateTime now = LocalDateTime.now();long nowSecond = now.toEpochSecond(ZoneOffset.UTC);long timestamp = nowSecond - BEGIN_TIMESTAMP;//2.生成序列号//2.1 获取当前日期,精确到天String date = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));//2.2自增长long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);//3.拼接返回return timestamp<<COUNT_BITS | count;//把COUNT_BITS时间戳往前面移动32位,后面的用count去插入。|代表的意思是,你count插入的一定成功}/*** 这个用来生成时间戳到目标年月日时分秒过的秒数。1689811200*//*   public static void main(String[] args) {//这个用来生成时间戳到当前年月日时分秒过的秒数。LocalDateTime time =LocalDateTime.of(2023,7,20,0,0,0);long second = time.toEpochSecond(ZoneOffset.UTC);System.out.println(second);}*/
}

3 单元测试+注解分析(难点较多)

对于 CountDownLatch、Lambda 的解释在代码后面

@Resourceprivate RedisIdWorker   redisIdWorker;//注入我们的配置类private ExecutorService es = Executors.newFixedThreadPool(500);//定义一个500的线程池@Test
void testIdWorker() throws InterruptedException {//redis全局唯一id的策略。CountDownLatch latch =new CountDownLatch(300); //countDownLatch相当于一个计数器,能够使一个线程等待( latch.await();)另外一些线程完成各自的工作后,// 再继续执行。这个计数器的初始值就是线程的数量,每当一个线程完成之后,计数器就进行减1,当计数器的值为0时,// 那么在countDownLatch上等待的线程就可以继续执行Runnable task=()->{     //这里是一个Lambda 表达式for (int i=0;i<100;i++){        //一次生成100个idLong id =redisIdWorker.nextId("order");//这个就是我们定义的类里面的方法“order是别名”System.out.println("id="+id);}latch.countDown();; //上面的for循环完一次,进行减一,减到0就执行下面的 latch.await();后面的操作};long begin =System.currentTimeMillis();for(int i=0;i<300;i++){    //程序其实从这里才开始,我们提交300个任务到线程里面,线程提交到task这个函数es.submit(task);}latch.await();//这里是当上面的latch为0后,开始启动这里long end =System.currentTimeMillis();System.out.println("time="+(end-begin));
}

3.1 countDownLatch前言

countDownLatch( 门阀、 计数器)是多线程控制的一种工具 ,它用来协调各个线程之间的同步。

countDownLatch相当于一个计数器,能够使一个线程等待另外一些线程完成各自的工作后,再继续执行。这个计数器的初始值就是线程的数量,每当一个线程完成之后,计数器就进行减1,当计数器的值为0时,那么在countDownLatch上等待的线程就可以继续执行。

countDownLatch接收一个int类型的参数,表示要等待的工作线程个数

public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException(“count < 0”);
this.sync = new Sync(count);
}

3.2 常用方法

方法 说明

await()	使当前线程进入同步队列进行等待,直到latch的值被减到0或者当前线程被中断,当前线程就会被唤醒。
await(long timeout, TimeUnit unit)	带超时时间的await()。
countDown()	使latch的值减1,如果减到了0,则会唤醒所有等待在这个latch上的线程
getCount()	获得latch的数值

原文链接:https://blog.csdn.net/qq_50652600/article/details/128075662
Lambda的超详细总结:https://blog.csdn.net/huangjhai/article/details/107110182

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

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

相关文章

pytest不使用 conftest.py 传递配置参数并设置全局变量

1. 创建config_handler.py import os import yaml# 当前路径(使用 abspath 方法可通过dos窗口执行) current_path os.path.dirname(os.path.abspath(__file__)) # 上上级目录 ffather_path os.path.abspath(os.path.join(current_path,"../../"))global_config_pat…

Java查询ES报错 I/O 异常解决方法: Request cannot be executed; I/O reactor status: STOPPED

问题 ES Request cannot be executed; I/O reactor status: STOPPED 报错解决 在使用ES和SpringBoot进行数据检索时&#xff0c;在接口中第一次搜索正常。第二次在搜索时在控制台就会输出Request cannot be executed; I/O reactor status: STOPPED错误 原因 本文错误是因为在使…

大语言模型-GPT-Generative Pre-Training

一、背景信息&#xff1a; GPT是2018 年 6 月由OpenAI 提出的预训练语言模型。 GPT可以应用于复杂的NLP任务中&#xff0c;例如文章生成&#xff0c;代码生成&#xff0c;机器翻译&#xff0c;问答对话等。 GPT也采用两阶段的训练过程&#xff0c;第一阶段是无监督的方式来预训…

7.23 字符串简单中等 520 125 14 34

520 Detect Capital 思路&#xff1a; 题目&#xff1a;判定word &#xff1a;if the usage of capitals in it is right.遍历所有的string&#xff1a; 两种情况&#xff1a; 首字母capitals–>判定第二个字母是否大写–>所有字母大写 otherwise 除第一个以外全部小写&a…

spring —— AOP(各类通知)

接&#xff1a;spring —— AOP&#xff08;前置通知&#xff09; 除前置通知&#xff08;Before&#xff09;外&#xff0c;AOP 里面还有返回通知&#xff08;AfterReturning&#xff09;、异常通知&#xff08;AfterThrowing&#xff09;、后置通知&#xff08;After&#x…

nginx的配置和使用

一、nginx支持win和linux版本的下载&#xff0c;选择合适的版本进行安装 二、配置文件注解 重点的几个参数进行注释&#xff1a; 1、listen 要监听的服务的端口&#xff0c;符合这个端口的才会被监听 server_name要监听的服务地址&#xff0c;可能是ip,也可能是域名&#xf…

Dav_笔记10:Using SQL Plan Management之4

SQL管理库 SQL管理库(SMB)是驻留在SYSAUX表空间中的数据字典的一部分。它存储语句日志,计划历史记录,SQL计划基准和SQL配置文件。为了允许每周清除未使用的计划和日志,SMB使用自动空间管理。 您还可以手动将计划添加到SMB以获取一组SQL语句。从Oracle Database 11g之前的…

Docker学习笔记(自用,不定期更新)

知识点&#xff1a; 容器是 Docker 的另一个核心概念。简单来说&#xff0c;容器是镜像的一个运行实例。所不同的是&#xff0c;镜像是静态的只读文件&#xff0c;而容器带有运行时需要的可写文件层&#xff0c;同时&#xff0c;容器中的应用进程处于运行状态。 容器保护三个…

41-50题矩阵和字符串 在Java中,将大写字符转换为小写字符的方法主要有以下几种:

20240723 一、数组最后几个和字符串的两个448. 找到所有数组中消失的数字&#xff08;和645. 错误的集合差不多&#xff09;283. 移动零118. 杨辉三角119. 杨辉三角 II661. 图片平滑器&#xff08;没看懂&#xff09;598. 区间加法 II566. 重塑矩阵303. 区域和检索 - 数组不可变…

键盘是如何使用中断机制的?当打印一串字符到显示屏上时发生了什么???

当在键盘上按下一个键时会进行一下操作&#xff1a; 1.当按下任意一个键时&#xff0c;键盘编码器监控会来判断按下的键是哪个 2.键盘控制器用将解码,将键盘的数据保存到键盘控制器里数据寄存器里面 3.此时发送一个中断请求给中断控制器&#xff0c;中断控制器获取到中断号发送…

全球性“微软蓝屏”事件反思:如何预防大规模系统故障

写在开头 近日&#xff0c;由于微软视窗系统软件更新引发的全球性“微软蓝屏”事件&#xff0c;再次将网络安全与系统稳定性的问题推上了风口浪尖。此次事件不仅成为科技领域的热点新闻&#xff0c;也对全球IT基础设施的韧性与安全性进行了一次深刻的检验。美国电脑安全技术公…

Elasticsearch介绍、安装以及IK分词器 --学习笔记

Elasticsearch 是什么&#xff1f; Elasticsearch 是一个高度可扩展的开源全文搜索和分析引擎。它允许你以极快的速度存储、搜索和分析大量数据。Elasticsearch 基于 Apache Lucene 构建&#xff0c;提供了一个分布式、多租户能力的全文搜索引擎&#xff0c;带有 HTTP web 接口…

深入MySQL中的IF和IFNULL函数

在数据库查询中&#xff0c;我们经常需要根据条件来决定数据的显示方式。MySQL提供了多种内置函数来帮助我们实现这种条件逻辑&#xff0c;其中IF和IFNULL是两个非常有用的函数。在这篇博客中&#xff0c;我们将深入探讨这两个函数的用法和它们在实际查询中的应用。 IF函数 I…

笔记小结:现代卷积神经网络之批量归一化

本文为李沐老师《动手学深度学习》笔记小结&#xff0c;用于个人复习并记录学习历程&#xff0c;适用于初学者 训练深层神经网络是十分困难的&#xff0c;特别是在较短的时间内使他们收敛更加棘手。 本节将介绍批量规范化&#xff08;batch normalization&#xff09;&#xf…

React中引入使用本地图片

1、css样式中&#xff0c;可以写成如下&#xff1a; .login {// 映射路径background: url(images/img-login.png)&#xff1b;background-size: 100% 100%; } .box{// 相对路径background: url(../assets/images/box.png)&#xff1b;background-size: 100% 100%; }2、在jsx文…

Redis-10大数据类型理解与测试

Redis10大数据类型 我要打10个1.redis字符串(String)2.redis列表(List)3.redis哈希表(Hash)4.redis集合(Set)5.redis有序集合(ZSet)6.redis地理空间(GEO)7.redis基数统计(HyperLogLog)8.redis位图(bitmap)9.redis位域(bitfield)10.redis流(Stream) 官网地址Redis 键(key)常用案…

Odoo Registry 源码解读:前端世界的魔法师

亲爱的Odoo探险家们,准备好踏上一段奇妙的代码冒险了吗?今天,我们要深入探索Odoo前端世界的一位神秘大师——Registry。它可能不像那些花哨的UI组件那样引人注目,但要知道,真正的高手都是低调的。Registry就像是Odoo世界里的甘道夫,默默地用魔法维持着整个中土世界的平衡…

卷与nfs实现多台主机容器之间的数据共享

容器存放数据到宿主机里 数据持久化&#xff1a;永久保存 数据共享&#xff1a;容器和容器 容器和宿主机 就是宿主机里的文件夹 /var/lib/docker/volumes docker 容器&#xff1a;容器运行起来是一个进程&#xff0c;进程的数据默认都在内存里&#xff0c;内存里的数据停电…

鸿蒙界面开发

界面开发 //构建 → 界面 build() {//行Row(){//列Column(){//文本 函数名(参数) 对象.方法名&#xff08;参数&#xff09; 枚举名.变量名Text(this.message).fontSize(40)//设置文本大小.fontWeight(FontWeight.Bold)//设置文本粗细.fontColor(#ff2152)//设置文本颜色}.widt…

邮件流量分析

邮件流量分析是指对邮件系统中进出的邮件数量、类型、流向以及相关性能指标进行统计和评估的过程。这种分析有助于优化邮件系统的性能、检测异常活动、防止垃圾邮件和网络攻击&#xff0c;以及改善邮件营销策略。邮件流量分析可以分为几个主要方面&#xff1a; 邮件统计&#x…