java雪花算法

news/2024/12/12 23:02:15/文章来源:https://www.cnblogs.com/HQING/p/18603635

雪花算法适用于高并发、分布式系统中生成唯一标识符。通过合理的位数设计,确保了ID的唯一性和有序性,非常适合需要快速生成唯一ID的场景。

雪花算法是一种分布式唯一ID生成算法,由Twitter开发。它生成的ID是64位的整数,具有时间排序的特性。其结构如下:

```
| 1 bit | 41 bits | 10 bits | 12 bits |
|-------|------------------|------------------|------------------|
| sign | timestamp | datacenter id | worker id | sequence |
```

- **sign(1 bit)**:始终为0,因为雪花算法不需要负数。
- **timestamp(41 bits)**:自定义纪元(如2021年1月1日)以来的毫秒数,最多可以支持69年的时间。
- **datacenter id(10 bits)**:数据中心 ID,最多支持1024个数据中心。
- **worker id(10 bits)**:工作机器 ID,最多支持1024个工作节点。
- **sequence(12 bits)**:在同一毫秒内生成的序列号,最多支持4096个 ID。

### 雪花算法 Java 实现

public class SnowflakeIdGenerator {
// 基本参数
private final static long EPOCH = 1609459200000L; // 自定义的开始时间(2021-01-01 00:00:00)
private final static long WORKER_ID_BITS = 10; // 工作机器ID占用的位数
private final static long DATACENTER_ID_BITS = 10; // 数据中心ID占用的位数
private final static long SEQUENCE_BITS = 12; // 序列号占用的位数// 计算各部分的位移
private final static long WORKER_ID_SHIFT = SEQUENCE_BITS; // 序列号位移
private final static long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS; // 数据中心ID位移
private final static long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS; // 时间戳位移// 生成掩码
private final static long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS); // 最大工作机器ID
private final static long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS); // 最大数据中心ID
private final static long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS); // 序列号掩码private long workerId; // 工作机器ID
private long datacenterId; // 数据中心ID
private long sequence = 0; // 序列号初始值
private long lastTimestamp = -1; // 上一次生成ID的时间戳public SnowflakeIdGenerator(long workerId, long datacenterId) {
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException("workerId必须在0到" + MAX_WORKER_ID + "之间");
}
if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId必须在0到" + MAX_DATACENTER_ID + "之间");
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}private long currentTimeMillis() {
return System.currentTimeMillis(); // 获取当前时间戳(毫秒)
}public synchronized long generateId() {
long timestamp = currentTimeMillis(); // 获取当前时间戳if (timestamp < lastTimestamp) {
throw new RuntimeException("时钟向后移动,无法生成ID");
}if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & SEQUENCE_MASK; // 在同一毫秒内序列号加1
if (sequence == 0) {
// 序列号已满,等待下一毫秒
while (timestamp <= lastTimestamp) {
timestamp = currentTimeMillis();
}
}
} else {
sequence = 0; // 重置序列号
}lastTimestamp = timestamp; // 更新上一次时间戳// 生成ID
return ((timestamp - EPOCH) << TIMESTAMP_SHIFT) |
(datacenterId << DATACENTER_ID_SHIFT) |
(workerId << WORKER_ID_SHIFT) |
sequence;
}// 示例:创建一个雪花算法实例并生成ID
public static void main(String[] args) {
long workerId = 1; // 机器ID
long datacenterId = 1; // 数据中心ID
SnowflakeIdGenerator generator = new SnowflakeIdGenerator(workerId, datacenterId);// 生成10个ID
for (int i = 0; i < 10; i++) {
System.out.println(generator.generateId());
}
}
}

 

### 代码说明:

1. **类定义**:`SnowflakeIdGenerator` 是生成唯一ID的类。

2. **基本参数**:
- `EPOCH`:定义开始时间(自1970年1月1日以来的毫秒数)。
- `WORKER_ID_BITS`、`DATACENTER_ID_BITS`、`SEQUENCE_BITS`:分别定义工作机器ID、数据中心ID和序列号占用的位数。

3. **位移计算**:
- `WORKER_ID_SHIFT`、`DATACENTER_ID_SHIFT`、`TIMESTAMP_SHIFT`:用于计算ID各个部分的位移。

4. **掩码计算**:
- `MAX_WORKER_ID`、`MAX_DATACENTER_ID`、`SEQUENCE_MASK`:用于限制机器ID、数据中心ID和序列号的最大值。

5. **构造方法**:
- `SnowflakeIdGenerator(long workerId, long datacenterId)`:初始化工作机器ID和数据中心ID,检查其合法性。

6. **时间戳获取**:
- `currentTimeMillis()`:获取当前时间的毫秒数。

7. **ID生成**:
- `generateId()`:生成唯一的ID,处理序列号自增和时间戳更新,确保在高并发情况下生成不重复的ID。

8. **主方法**:
- `main(String[] args)`:创建 `SnowflakeIdGenerator` 实例并生成10个唯一的ID。

 更多实用教程资源:http://sj.ysok.net/jydoraemon 访问码:JYAM

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

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

相关文章

html基础-表格

表格标签的简单介绍:<table><tr><th></th><td></td></tr> </table> <!--table是表格标签 tr是行 td是每一个单元格 th是表头,有加粗剧中的功能 他们之间是需要互相嵌套 tr必须嵌套在table td和th必须签到到tr之中--> …

001 星际蜗牛 黑群晖 配置 安装

星际蜗牛 硬盘位置RAID的类型都是 Basic, 不需要做磁盘阵列。文件系统选择:ext4 ,比较稳定。NAS 结构图:系统盘:硬盘2 | 固态M2 : 32GB【系统盘】第一层:硬盘4 | 插口坏了 西数 WD1600AAJS-08PSA0 149.1GB 【大旧衰】第二层:硬盘3 | 东芝 TOSHIBA MQ01ABD050 46…

002 群晖中用VMM(Virtual Machine Manager)再虚拟安装一台群晖

安装环境:VMware Workstation Pro15虚拟黑群晖机器型号:DS3617xsDSM 版本:DSM 6.2-23739 分配内存8G如图:群晖的安装略过,需要的自行搜索大妈站内文章。1. 搜索Virtual Machine Manager(以下简称DMM)并安装设为头图套件中心中,直接搜索Virtual Machine Manager(不要搜V…

Spring Cloud 搭建 Nacos (windows )

一、Nacos服务搭建 1、下载安装: Windows: 在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码: GitHub主页:https://github.com/alibaba/nacos GitHub的Release下载页:https://github.com/alibaba/nacos/releases 解压后出现目录:说明:(默认…

一、HTML基础实例

1.HTML 文档 (1)所有 HTML 文档都必须以文档类型声明开头: 。 (2)HTML 文档以 开始,以 结束。 (3)HTML 文档的可见部分位于 和 之间。 实例: <!DOCTYPE html> <html> <body><h1>我的第一个标题</h1> <p>我的第一个段落。</…

node和rasa交互之可通信

本文主要实现node和rasa的交互,这样为后面node介入rasa奠定基础,目前实现的是node获取rasa响应后的结果,从接口访问rasa然后返回rasa的结果。涉及如何配置,训练模型,启动rasa服务器,打通路由,交互。1.2 通过node和rasa交互 1.2.1 配置 更改 config.yml # The config rec…

网络安全系统学习实验1:RDP远程登录配置

网络安全系统学习实验1:RDP远程登录配置 准备工作: 0、准备好虚拟机1、服务器侧(虚拟机Windows 2003-01)IP地址: # 获得服务器的IP地址192.168.58.223 ipconfig /all2、客户端侧(虚拟机Win7 pte_czj)IP地址: # 客户端侧IP地址192.168.58.222 ipconfig /all1、启用远程桌面…

使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南

目标检测技术作为计算机视觉领域的核心组件,在自动驾驶系统、智能监控、零售分析以及增强现实等应用中发挥着关键作用。本文将详细介绍PaliGemma2模型的微调流程,该模型通过整合SigLIP-So400m视觉编码器与Gemma 2系列的高级语言模型,专门针对目标检测任务进行了优化设计。 本…

APP 内存泄露优化

原理 https://juejin.cn/post/6864492188404088846 分析 我的APP主要的VC路径如下:如果没有内存泄露的话,我们从一个VC_A开始push一个VC_B,无论在VC_B操作了什么,pop回到VC_A,这个时候的内存大小应该和VC_A在puhs VC_B的时候是一样大的。 如图: 页面结构:曲谱列表 push 曲…

VMware ESXi 8.0U3c macOS Unlocker OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版)

VMware ESXi 8.0U3c macOS Unlocker & OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版)VMware ESXi 8.0U3c macOS Unlocker & OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版) 发布 ESXi 8.0U3 集成驱动版,在个人电脑上运行企业级工作负载 请访问原文链接:…

12.12实验八:随机森林算法实现与测试

实验八:随机森林算法实现与测试 一、实验目的 深入理解随机森林的算法原理,进而理解集成学习的意义,能够使用 Python 语言实现随机森林算法的训练与测试,并且使用五折交叉验证算法进行模型训练与评估。二、实验内容 (1)从 scikit-learn 库中加载 iris 数据集,使用留出法…