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

【数据结构与算法】Snowflake雪花算法Java实现

Snowflake产生的ID由 64 bit 的二进制数字组成,被分成了4个部分,每一部分存储的数据都有特定的含义:

  • 第 0 位: 符号位(标识正负),始终为 0;
  • 第 1~41 位 :一共 41 位,用来表示时间戳,单位是毫秒,可以支撑2 ^41 毫秒(约 69 年)2^41/1000*60*60*24*365 = 69年
  • 第 42~52 位 :一共 10 位,工作机器id,一般用前 5 位表示机房ID,后 5 位表示机器ID,用于区分不同集群/机房的节点,10位的长度,可以表示1024个不同节点。
  • 第 53~64 位 :一共 12 位,用来表示序列号。 序列号为自增值,代表单台机器每毫秒能够产生的最大ID 数(2^12 = 4096),也就是说单台机器每毫秒最多可以生成 4096 个 唯一 ID,最大可以支持400w左右的并发量。
/*** 雪花算法* @author CC* @version 1.0* @since2023/10/24*/
public class SnowFlake {// 机房(数据中心)IDprivate long datacenterId;// 机器IDprivate long workerId;// 同一时间的序列号private long sequence;// 开始时间戳private long twepoch = 1634393012000L;// 机房ID所占的位数: 5个bitprivate long datacenterIdBits = 5L;// 机器ID所占的位数:5个bitprivate long workerIdBits = 5L;// 最大机器ID:5bit最多只能有31个数字,就是说机器id最多只能是32以内// 最大:11111(2进制) --> 31(10进制)private long maxWorkerId = -1L ^ (-1L << workerIdBits);// 最大机房ID:5bit最多只能有31个数字,机房id最多只能是32以内// 最大:11111(2进制)--> 31(10进制)private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);// 同一时间的序列所占的位数:12个bit// 最大111111111111 = 4095  代表同一毫秒最多生成4096个private long sequenceBits = 12L;// workerId的偏移量12private long workerIdShift = sequenceBits;// datacenterId的偏移量12+5private long datacenterIdShift = sequenceBits + workerIdBits;// timestampLeft的偏移量12+5+5private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;// 序列号掩码 4095 (0b111111111111=0xfff=4095)// 用于序号的与运算,保证序号最大值在0-4095之间private long sequenceMask = -1L ^ (-1L << sequenceBits);// 最近一次时间戳private long lastTimestamp = -1L;// 按照机器ID和机房ID创建雪花算法对象public SnowFlake(long workerId, long datacenterId) {this(workerId, datacenterId, 0);}public SnowFlake(long workerId, long datacenterId, long sequence) {// 合法判断if (workerId > maxWorkerId || workerId < 0) {throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));}if (datacenterId > maxDatacenterId || datacenterId < 0) {throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));}System.out.printf("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d",timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);this.workerId = workerId;this.datacenterId = datacenterId;this.sequence = sequence;}// 获取下一个随机的IDpublic synchronized long nextId() {// 获取当前时间戳,单位毫秒long timestamp = timeGen();if (timestamp < lastTimestamp) {System.err.printf("clock is moving backwards.  Rejecting requests until %d.", lastTimestamp);throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds",lastTimestamp - timestamp));}// 同一毫秒并发if (lastTimestamp == timestamp) {// 同一毫秒(时间戳)内进行序列号递增sequence = (sequence + 1) & sequenceMask;// sequence序列大于4095,导致溢出if (sequence == 0) {// 调用到下一个时间戳的方法timestamp = tilNextMillis(lastTimestamp);}} else {// 如果是当前时间的第一次获取,那么就置为0sequence = 0;}// 记录上一次的时间戳lastTimestamp = timestamp;// 偏移计算return ((timestamp - twepoch) << timestampLeftShift) |(datacenterId << datacenterIdShift) |(workerId << workerIdShift) |sequence;
}// 计算时间戳private long tilNextMillis(long lastTimestamp) {// 获取最新时间戳long timestamp = timeGen();// 如果发现最新的时间戳小于或者等于序列号已经超4095的那个时间戳while (timestamp <= lastTimestamp) {// 不符合则继续timestamp = timeGen();}return timestamp;}// 获取当前时间戳private long timeGen() {return System.currentTimeMillis();}public static void main(String[] args) {SnowFlake worker = new SnowFlake(1, 1);for (int i = 0; i < 100; i++) {System.out.println(worker.nextId());}System.out.println();worker = new SnowFlake(1, 2);for (int i = 0; i < 100; i++) {System.out.println(worker.nextId());}}
}

 

相关文章:

【数据结构与算法】Snowflake雪花算法Java实现

Snowflake产生的ID由 64 bit 的二进制数字组成&#xff0c;被分成了4个部分&#xff0c;每一部分存储的数据都有特定的含义&#xff1a; 第 0 位&#xff1a; 符号位&#xff08;标识正负&#xff09;&#xff0c;始终为 0&#xff1b;第 1~41 位 &#xff1a;一共 41 位&…...

重要功能更新:妙手正式接入SHEIN供货模式(OBM)店铺,赋能卖家把握出海新机遇!

继接入SHEIN平台模式店铺之后&#xff0c;妙手ERP积极响应卖家需求&#xff0c;正式接入SHEIN供货模式&#xff08;OBM&#xff09;店铺&#xff0c;并支持产品采集、批量刊登、产品管理等功能&#xff0c;帮助跨境卖家快速上品、高效运营&#xff0c;把握出海新机遇。 SHEIN供…...

和鲸ModelWhale与中科可控X系列异构加速服务器完成适配认证,搭载海光芯片,构筑AI算力底座

AIGC 时代&#xff0c;算力作为新型生产力&#xff0c;是国家和企业构建竞争优势的关键。而随着传统计算方式无法满足新时代激增的算力需求&#xff0c;计算场景的多元化和计算应用的复杂化推动了 CPUGPU 异构平台的加速组建。在此全球激烈角逐的大趋势下&#xff0c;我国信创产…...

Vue单文件组件

一、.vue文件 我们使用Vue的单文件组件的时候&#xff0c;一个.vue文件就是一个组件。 例如我们创建一个School组件&#xff1a; 二、组件的结构 我们编写网页代码的时候有HTML结构、CSS样式、JS交互。 组件里也是同样存在这三种结构的&#xff1a; <template><d…...

轻松理解 Transformers(1):Input部分

编者按&#xff1a;Transformers 是人工智能领域近年来最引人瞩目的技术之一&#xff0c;它为语言生成模型的发展做出了巨大的贡献。随着大语言模型&#xff08;LLM&#xff09;的兴起&#xff0c;公众对其背后的技术原理也越来越感兴趣。但是由于Transformers本身具有一定的复…...

PHP MySQL 交互 笔记/练习

PHP 与 MySQL 交互 交互函数 函数名作用mysqli_connect()与MySQL 数据库建立连接。mysqli_close()关闭与MYSQL 数据库建立的连接。mysqli_connect_errno()与MySQL 数据库建立连接时&#xff0c;发生错误时的错误编号。mysqli_connect_error()与MySQL 数据库建立连接时&#x…...

领域驱动设计:基于DDD的微服务设计实例

文章目录 项目基本信息战略设计战术设计后续的工作 用一个项目来了解 DDD 的战略设计和战术设计&#xff0c;走一遍从领域建模到微服务设计的全过程&#xff0c;一起掌握 DDD 的主要设计流程和关键 点。 项目基本信息 项目的目标是实现在线请假和考勤管理。功能描述如下&…...

【PB续命02】Oracle中加密及编码等

Oracle中实现Md5/Base64/AesBase64/UrlEncode等加密编码的使用备忘&#xff0c;参考其它人的贴子&#xff0c;Oracle 11g 亲测有效。 1. Oracle中实现Md5加密 SELECT lower(MD5(白龙马5217)) FROM dual; --返回结果 72853926982028ab8219921ad2918b8f --或 select utl_raw.…...

STM32-LTC6804方案成熟BMS方案

方案下载链接&#xff01;&#xff01;https://mp.weixin.qq.com/s?__bizMzU2OTc4ODA4OA&mid2247549092&idx1&snc73855c4e3d5afddd8608d8528864f95&chksmfcfb1373cb8c9a65a4bd1f545a1a587af882f209e7ccbb8944f4d2514d241ca1d7fcc4615e10&token539106225&a…...

一步一步认知机器学习

1&#xff0c;前言 之前学习并且实操了一些算法框架用来探索相关方向的可能性&#xff0c;但是总不了解相关的步骤。因为一步一步按照别人给出的步骤去操作&#xff0c;解决一些操作时出现的问题&#xff0c;基本可以达到目的。但是这个也基本限制了在那个框架而已。对于算法还…...

现代C++、STL、QTL的使用

0、现代C中最重要的是&#xff1a; 右值引用&&、移动语义std::move、完美转发std::forward、万能引用T&& void Func(int& x) { cout << "左值引用" << endl; } void Func(const int& x) { cout << "const左值引用…...

Android 备案公钥、签名 MD5获取方法

公钥和 MD5 值可以通过安卓开发工具、Keytool、Jadx-GUI 等多种工具获取&#xff0c;本文以 jadx-gui 为例。 1 windows 下载 jadx-gui 工具 下载 jadx-gui 工具 在这里选择一个下载 下载后 解压文件 双击运行程序&#xff0c;然后选择 release apk安装包 2 Mac 打开终端&a…...

1688拍立淘接口,按图搜索商品接口,图片识别接口,图片上传搜索接口,图片搜索API接口,以图搜货接口

1688拍立淘接口的作用是让用户通过上传图片或输入图片链接的方式&#xff0c;调用1688的图片搜索引擎&#xff0c;返回与该图片相关的所有1688商品。 使用该接口需要先获取一个key和secret&#xff0c;然后参考API文档里的接入方式和示例&#xff0c;查看测试工具是否有需要的…...

H3C AC通过Web平台进行AC软件的升级?

软件升级的流程 1、获取软件版本 登录新华三官网&#xff08;首页>产品支持与服务>文档与软件>软件下载&#xff09;&#xff0c;将指定的软件版本下载至本地。 无线路由器-无线接入点-无线控制器-新华三集团-H3C 官网软件下载公共账号密码&#xff1a;账号&#x…...

网络通信和tcp协议

一、计算机网络架构模型 1、OSI七层模型 2、TCP/IP模型 3、TCP/IP协议族 无论是什么网络模型&#xff0c;都是为上一层提供服务&#xff0c;抽象层建立在低一层提供的服务上&#xff0c;每层都对应不同的协议 4、地址和端口号 1&#xff09;MAC地址 MAC 地址共 48 位&#…...

React 核心与实战2023版

课程亮点: 完整的前后台项目(PC+移动;完成业务;)React 最新企业标准技术栈(React 18 + Redux + ReactRouter + AntD)React + TypeScript (为大型项目奠定了基础)课程内容安排: React 介绍 React 是什么? React 是由Meta公司研发,是一个用于 构建Web和原生交互界面…...

在 Android 上测试 Kotlin 协程

文章目录 官方文档在测试中调用挂起函数TestDispatchersStandardTestDispatcherUnconfinedTestDispatcher 注入测试调度程序设置主调度程序在测试之外创建调度程序创建您自己的 TestScope注入作用域 官方文档 https://developer.android.google.cn/kotlin/coroutines/test?hl…...

图论04-【无权无向】-图的广度优先遍历BFS

文章目录 1. 代码仓库2. 广度优先遍历图解3.主要代码4. 完整代码 1. 代码仓库 https://github.com/Chufeng-Jiang/Graph-Theory 2. 广度优先遍历图解 3.主要代码 原点入队列原点出队列的同时&#xff0c;将与其相邻的顶点全部入队列下一个顶点出队列出队列的同时&#xff0c;将…...

vue3 v-model的使用

&#x1f642;博主&#xff1a;锅盖哒 &#x1f642;文章核心&#xff1a;vue3 v-model的使用 目录 前言 什么是v-model&#xff1f; 基本的v-model用法 自定义组件中的v-model 前言 当涉及到Vue.js 3的前端开发时&#xff0c;v-model是一个不可或缺的工具&#xff0c;它…...

Ubuntu 20.04 安装 Docker

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家来访。 介绍 Docker容器具有以下三大特点&#xff1a; 轻量化&#xff1a;一台主机上运行的多个Dock…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...