当前位置: 首页 > news >正文

雪花算法,在分布式环境下实现高效的ID生成

其实雪花算法比较简单,可能称不上什么算法就是一种构造UID的方法。
点1:UID是一个long类型的41位时间戳,10位存储机器码,12位存储序列号。
点2:时间戳的单位是毫秒,可以同时链接1024台机器,每台机器每毫秒可以使用4096个序列好,我们会给生成id上一个同步锁,阻塞住其他线程的访问。
点3:利用掩码我们可以检测序列是否溢出,如果溢出的话,就强制等待到下一毫秒。


/*** @author hardstone* @since 29 July 2023(1690603385473)*/
public class SnowFlakes {//开始的时间戳private final  long start = 1690603385473L;//机器标识长度5位private final long machineIdBits = 5L;//机器集群标识长度5位private final long centerIdBits = 5L;//序列标识所占位数12位private final long sequenceBits = 12L;//机器标识最大值private final long maxMachineId = -1L ^ (-1L << machineIdBits);//机器集群标识最大值private final long maxCenterId = -1L ^ (-1L << centerIdBits);//序列标识的最大值private final long sequenceMask = -1L ^ (-1L << sequenceBits);//机器标识左移长度private final long machineIdShift = sequenceBits;//机器集群标识左移长度private final long centerIdShift = sequenceBits + machineIdBits;//时间戳左移长度private final long timeStampIdShift = sequenceBits + machineIdBits + centerIdBits;//序列Idprivate long sequence = 0L;//机器Idprivate long machineId;//机器集群Idprivate long centerId;//时间戳private long lastTimeStamp = -1L;public SnowFlakes(long machineId, long centerId) {if (machineId > maxMachineId || machineId < 0) {throw new IllegalArgumentException(String.format("WorkerId should be between 0 and 31"));}if (centerId > maxCenterId || centerId < 0) {throw new IllegalArgumentException(String.format("CenterId should be between 0 and 31"));}}public synchronized long nextId() {long timeStamp = System.currentTimeMillis();//时间回滚现象if (timeStamp < lastTimeStamp) {throw new RuntimeException(String.format("Time gone backwards!"));}if (lastTimeStamp == timeStamp) {sequence = (sequence + 1) & sequenceMask;//如果序列分配完了if (sequence == 0) {timeStamp = getNextMillis(lastTimeStamp);}} else {sequence = 0L;}lastTimeStamp = timeStamp;return ((timeStamp - start) << timeStampIdShift)| (centerId << centerIdShift)| (machineId << machineIdShift)| sequence;}protected long getNextMillis(long lastTimeStamp) {long timeStamp = System.currentTimeMillis();while (timeStamp <= lastTimeStamp) {timeStamp = System.currentTimeMillis();}return timeStamp;}public static void main(String[] args) {System.out.println(new SnowFlakes(0, 0).nextId());}
}
http://www.lryc.cn/news/100077.html

相关文章:

  • 使用css 动画实现,水波纹的效果
  • Unity光照相关知识和实践 (烘焙光照,环境光设置,全局光照)
  • 【设计模式——学习笔记】23种设计模式——适配器模式Adapter(原理讲解+应用场景介绍+案例介绍+Java代码实现)
  • Android Unit Test
  • docker更新jenkins
  • 一种新的基于区域的在线活动轮廓模型研究(Matlab代码实现)
  • 【Docker】基于Dockerfile搭建LNMP架构
  • 爬虫003_pycharm的安装以及使用_以及python脚本模版设置---python工作笔记021
  • 远程xml读取解析,将image url下载到本地,延时队列定时删除文件,图片访问路径保存在数据库中
  • firefox笔记-Centos7离线安装firefox
  • Flutter:滑动面板
  • RocketMQ概论
  • 任务的创建与删除
  • 致敬图灵!HashData拥抱数据智能新时代!
  • AD21原理图的高级应用(二)层次原理图设计
  • ROS中使用RealSense-D435
  • nlp系列(6)文本实体识别(Bi-LSTM+CRF)pytorch
  • zookeeper-3.7.1集群
  • ubuntu上安装firefox geckodriver 实现爬虫
  • 【Matlab】基于长短期记忆网络的时间序列预测(Excel可直接替换数据)
  • [NLP]LLM高效微调(PEFT)--LoRA
  • vue3 vant上传图片
  • 深入理解linux内核--内存管理
  • SpringBoot热部署的开启与关闭
  • k8s集群部署(使用kubeadm部署工具进行快速部署,相关对应版本为docker20.10.0+k8s1.23.0+flannel)
  • 20230729 git github gitee
  • php建造者模式
  • linux---》用户操作/su和sudo/普通权限/特殊权限/解压压缩/软件管理,rpm和yum/源码安装nginx
  • tinkerCAD案例:20. Simple Button 简单按钮和骰子
  • Java - 为什么要用BigDecimal?