雪花算法程序实现及史上最全解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 雪花算法实现及介绍 (生产可以直接使用)
importorg.junit.Test;
importorg.junit.runner.RunWith;
importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/*** @author 86182* @date 2023/6/5 15:49* @desc*/publicclassSnowFlakeDemo {
/**起始的时间戳,用于计算时间戳部分*/privatefinalstaticlongSTART_STMP=1480166465631L;
/**序列号占用的位数*/privatefinalstaticlongSEQUENCE_BIT=12;
/**机器标识占用的位数 */privatefinalstaticlongMACHINE_BIT=5;
/**数据中心占用的位数 */privatefinalstaticlongDATA_CENTER_BIT=5;
/**数据中心最大值*//*** 这个运算`-1L ^ (-1L << DATA_CENTER_BIT)`的含义是:* - -1L << DATA_CENTER_BIT是将-1的二进制表示向左移动DATA_CENTER_BIT位,也就是5位。* - 由于-1的二进制表示是除了最高位都是1,向左移动5位后,低5位是1,高位都是0。* - 然后使用`^`运算,即异或运算对-1和向左移动的结果进行运算。* - 由于异或运算遵循交换律和结合律,且异或相同为0,不同为1。* - 所以,最终得到的结果是高5位是1,低位都是0,也就是一个5位的二进制数,其十进制结果就是2^5 - 1 = 31。* 所以,简单来说,该运算的结果是获取一个位数为DATA_CENTER_BIT的二进制数,并将其转换为十进制 - 这里就是31。*/privatefinalstaticlongMAX_DATA_CENTER_NUM=-1L^ (-1L<<DATA_CENTER_BIT);
/**机器标识最大值*/privatefinalstaticlongMAX_MACHINE_NUM=-1L^ (-1L<<MACHINE_BIT);
/**序列号最大值*/privatefinalstaticlongMAX_SEQUENCE=-1L^ (-1L<<SEQUENCE_BIT);
/**机器标识左移位数,12位*/privatefinalstaticlongMACHINE_LEFT=SEQUENCE_BIT;
/**数据中心左移位数,12+5=17位*/privatefinalstaticlongDATA_CENTER_LEFT=SEQUENCE_BIT+MACHINE_BIT;
/**时间戳左移位数,12+5+5=22位*/privatefinalstaticlongTIMESTMP_LEFT=DATA_CENTER_LEFT+DATA_CENTER_BIT;
/**数据中心ID*/privatelongdataCenterId;
/**机器标识ID*/privatelongmachineId;
/**序列号 (备注:对于并发度不高的系统而言,此序列号始终是0,生成的雪花Id末尾一位数字始终为偶数!!!)*/privatelongsequence=0L;
/**上一次时间戳*/privatelonglastStmp=-1L;
publicSnowFlakeDemo(){}
publicSnowFlakeDemo(longdataCenterId, longmachineId) {
/**检验数据中心ID和机器ID合法性,不合法抛出异常*/if (dataCenterId>MAX_DATA_CENTER_NUM||dataCenterId<0) {
thrownewIllegalArgumentException("dataCenterId can't be greater than MAX_DATA_CENTER_NUM or less than 0");
        }
if (machineId>MAX_MACHINE_NUM||machineId<0) {
thrownewIllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
        }
/**合法的情况下将参数赋值给类成员变量*/this.dataCenterId=dataCenterId;
this.machineId=machineId;
    }
/**产生下一个ID*/publicsynchronizedlongnextId() {
/**获取当前时间戳,毫秒级*/longcurrStmp=getNewstmp();
/**时间戳回拨,抛出异常*/if (currStmp<lastStmp) {
thrownewRuntimeException("Clock moved backwards.  Refusing to generate id");
        }
/**如果时间戳与上一次相同,序列号自增*/if (currStmp==lastStmp) {
/*** (sequence + 1) & MAX_SEQUENCE 的含义是:* 1. sequence + 1 首先将序列号sequence增加1。* 2. & MAX_SEQUENCE 然后与序列号最大值MAX_SEQUENCE进行与运算。* 3. 由于与运算遵循交换律和结合律,且相同为1,不同为0。* 4. 所以,如果sequence增加后的值没有超过MAX_SEQUENCE,则与运算结果不变,sequence增加后的值仍然保留。* 5. 但如果sequence增加后的值超过了MAX_SEQUENCE,则与运算会将超出的高位全部抹去,只保留低MAX_SEQUENCE位,使得sequence不会超过该最大值。* 所以,该运算的效果是,每次让sequence增加1,但sequence增加后的值不会超过我们设置的MAX_SEQUENCE最大值,一旦超过,高位会被抹去,重新回到低MAX_SEQUENCE位。*/sequence= (sequence+1) &MAX_SEQUENCE;
/**同一毫秒序列号已经最大,等待下一毫秒*/if (sequence==0L) {
currStmp=getNextMill();
            }
        } else {
/**不同毫秒序列号置为0,从0开始*/sequence=0L;
        }
/**更新时间戳为当前时间戳*/lastStmp=currStmp;
/*** 计算ID* 时间戳部分(41 bit)*     数据中心部分(5 bit)*         机器标识部分(5 bit)*             序列号部分(12 bit)*//*** 含义是:* 1. (currStmp - START_STMP) << TIMESTMP_LEFT 首先计算出当前时间戳currStmp减去起始时间戳START_STMP的差值,然后将该差值向左移动TIMESTMP_LEFT位,也就是41位。这步骤生成时间戳部分。* 2. | dataCenterId << DATA_CENTER_LEFT  将数据中心ID向左移动DATA_CENTER_LEFT位,也就是17位,然后使用按位或|运算符将该结果与1步骤的结果进行|运算。这步骤在时间戳部分的基础上添加了数据中心ID部分。* 3. | machineId << MACHINE_LEFT 将机器ID向左移动MACHINE_LEFT位,也就是22位,然后使用按位或运算符将该结果与2步骤的结果进行|运算。这步骤在时间戳部分和数据中心ID部分的基础上添加了机器ID部分。* 4. | sequence 最后,直接使用按位或运算符将序列号sequence与3步骤的结果进行|运算,添加序列号部分,得到最终完整的ID。* 5. 通过这4步运算,我们按照时间戳→数据中心ID→机器ID→序列号的顺序,一步步构建完整的ID。这与雪花ID的结构与顺序是一致的。* 所以,这句运算的含义就是按照部分→部分的方式构建完整的雪花ID,每一步都使用按位或运算,这是一种高效的ID构建方式。这是雪花算法实现的关键所在。*/return (currStmp-START_STMP) <<TIMESTMP_LEFT|dataCenterId<<DATA_CENTER_LEFT|machineId<<MACHINE_LEFT|sequence;
    }
/*** 等待下一毫秒** @return*/privatelonggetNextMill() {
longmill=getNewstmp();
while (mill<=lastStmp) {
mill=getNewstmp();
        }
returnmill;
    }
/*** 获取当前时间戳,毫秒级* @return*/privatelonggetNewstmp() {
returnSystem.currentTimeMillis();
    }
}


相关文章
|
1天前
|
存储 算法 安全
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。
|
26天前
|
机器学习/深度学习 人工智能 算法
深入解析图神经网络:Graph Transformer的算法基础与工程实践
Graph Transformer是一种结合了Transformer自注意力机制与图神经网络(GNNs)特点的神经网络模型,专为处理图结构数据而设计。它通过改进的数据表示方法、自注意力机制、拉普拉斯位置编码、消息传递与聚合机制等核心技术,实现了对图中节点间关系信息的高效处理及长程依赖关系的捕捉,显著提升了图相关任务的性能。本文详细解析了Graph Transformer的技术原理、实现细节及应用场景,并通过图书推荐系统的实例,展示了其在实际问题解决中的强大能力。
135 30
|
5天前
|
存储 监控 算法
企业内网监控系统中基于哈希表的 C# 算法解析
在企业内网监控系统中,哈希表作为一种高效的数据结构,能够快速处理大量网络连接和用户操作记录,确保网络安全与效率。通过C#代码示例展示了如何使用哈希表存储和管理用户的登录时间、访问IP及操作行为等信息,实现快速的查找、插入和删除操作。哈希表的应用显著提升了系统的实时性和准确性,尽管存在哈希冲突等问题,但通过合理设计哈希函数和冲突解决策略,可以确保系统稳定运行,为企业提供有力的安全保障。
|
30天前
|
存储 算法
深入解析PID控制算法:从理论到实践的完整指南
前言 大家好,今天我们介绍一下经典控制理论中的PID控制算法,并着重讲解该算法的编码实现,为实现后续的倒立摆样例内容做准备。 众所周知,掌握了 PID ,就相当于进入了控制工程的大门,也能为更高阶的控制理论学习打下基础。 在很多的自动化控制领域。都会遇到PID控制算法,这种算法具有很好的控制模式,可以让系统具有很好的鲁棒性。 基本介绍 PID 深入理解 (1)闭环控制系统:讲解 PID 之前,我们先解释什么是闭环控制系统。简单说就是一个有输入有输出的系统,输入能影响输出。一般情况下,人们也称输出为反馈,因此也叫闭环反馈控制系统。比如恒温水池,输入就是加热功率,输出就是水温度;比如冷库,
233 15
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
63 1
|
2月前
|
存储 缓存 算法
通过优化算法和代码结构来提升易语言程序的执行效率
通过优化算法和代码结构来提升易语言程序的执行效率
|
2月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
75 4
|
2月前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
86 2
|
8天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析

推荐镜像

更多