千家信息网

Java怎么通过手写分布式雪花SnowFlake生成ID

发表于:2025-11-10 作者:千家信息网编辑
千家信息网最后更新 2025年11月10日,本文小编为大家详细介绍"Java怎么通过手写分布式雪花SnowFlake生成ID",内容详细,步骤清晰,细节处理妥当,希望这篇"Java怎么通过手写分布式雪花SnowFlake生成ID"文章能帮助大家
千家信息网最后更新 2025年11月10日Java怎么通过手写分布式雪花SnowFlake生成ID

本文小编为大家详细介绍"Java怎么通过手写分布式雪花SnowFlake生成ID",内容详细,步骤清晰,细节处理妥当,希望这篇"Java怎么通过手写分布式雪花SnowFlake生成ID"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

SnowFlake算法

SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图:

分为四段:

第一段: 1位为未使用,永远固定为0。

(因为二进制中最高位是符号位,1表示负数,0表示正数。生成的id一般都是用正整数,所以最高位固定为0 )

第二段: 41位为毫秒级时间(41位的长度可以使用69年)

第三段: 10位为workerId(10位的长度最多支持部署1024个节点)

(这里的10位又分为两部分,第一部分5位表示数据中心ID(0-31)第二部分5位表示机器ID(0-31))

第四段: 12位为毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)

代码实现:

import java.util.HashSet;import java.util.concurrent.atomic.AtomicLong;public class SnowFlake {    //时间 41位    private static long lastTime = System.currentTimeMillis();    //数据中心ID 5位(默认0-31)    private long datacenterId = 0;    private long datacenterIdShift = 5;    //机房机器ID 5位(默认0-31)    private long workerId = 0;    private long workerIdShift = 5;    //随机数 12位(默认0~4095)    private AtomicLong random = new AtomicLong();    private long randomShift = 12;    //随机数的最大值    private long maxRandom = (long) Math.pow(2, randomShift);    public SnowFlake() {    }    public SnowFlake(long workerIdShift, long datacenterIdShift){        if (workerIdShift < 0 ||                datacenterIdShift < 0 ||                workerIdShift + datacenterIdShift > 22) {            throw new IllegalArgumentException("参数不匹配");        }        this.workerIdShift = workerIdShift;        this.datacenterIdShift = datacenterIdShift;        this.randomShift = 22 - datacenterIdShift - workerIdShift;        this.maxRandom = (long) Math.pow(2, randomShift);    }    //获取雪花的ID    private long getId() {        return lastTime << (workerIdShift + datacenterIdShift + randomShift) |                workerId << (datacenterIdShift + randomShift) |                datacenterId << randomShift |                random.get();    }    //生成一个新的ID    public synchronized long nextId() {        long now = System.currentTimeMillis();        //如果当前时间和上一次时间不在同一毫秒内,直接返回        if (now > lastTime) {            lastTime = now;            random.set(0);            return getId();        }        //将最后的随机数,进行+1操作        if (random.incrementAndGet() < maxRandom) {            return getId();        }        //自选等待下一毫秒        while (now <= lastTime) {            now = System.currentTimeMillis();        }        lastTime = now;        random.set(0);        return getId();    }    //测试    public static void main(String[] args) {        SnowFlake snowFlake = new SnowFlake();        HashSet set = new HashSet<>();        for (int i = 0; i < 10000; i++) {            set.add(snowFlake.nextId());        }        System.out.println(set.size());    }}

代码中获取id的方法利用位运算实现

1 | 41 | 5 | 5 | 12

0|0001100 10100010 10111110 10001001 01011100 00|00000|0 0000|0000 00000000 //41位的时间

0|000000‭0 00000000 00000000 00000000 00000000 00|10001|0 0000|0000 00000000 //5位的数据中心ID

0|0000000 00000000 00000000 00000000 00000000 00|00000|1 1001|0000 00000000 //5为的机器ID

or 0|0000000 00000000 00000000 00000000 00000000 00|00000|0 0000|‭0000 00000000‬ //12位的sequence

------------------------------------------------------------------------------------------

0|0001100 10100010 10111110 10001001 01011100 00|10001|1 1001|‭0000 00000000‬ //结果:910499571847892992

SnowFlake优点:

所有生成的id按时间趋势递增整个分布式系统内不会产生重复id(因为有datacenterId和workerId来做区分) SnowFlake不足:

由于SnowFlake强依赖时间戳,所以时间的变动会造成SnowFlake的算法产生错误。

读到这里,这篇"Java怎么通过手写分布式雪花SnowFlake生成ID"文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注行业资讯频道。

生成 时间 分布式 雪花 数据 数据中心 文章 机器 算法 随机数 最高 代码 内容 整数 结果 节点 长度 支持 妥当 二进制 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 安装禅道本地用装数据库么 贵阳软件开发峰会 上海服务器电路板回收 设计数据库表注意什么问题 全军首届军营网络安全宣传周 灵石县网络安全 戴尔1u服务器 掌尚盘出现未配置数据库怎么解决 网络安全进国家哪个部门 经营范围软件开发类查询 两会关于网络安全的话题 上海交易软件开发服务费 桐乡合丰网络技术有限公司 验证失败链接服务器错误 软件开发商评价 原告青岛五铢钱网络技术公司 数据库在容器中怎么重启 工业软件开发核心 软件开发服务费转增资本 网络技术学的什么 数据库在电子商务中的作用 测试idea的数据库连接 360互联网重大科技成果 网站每年还要服务器费用吗 网络安全保护平台建设使用 服务器过期网站需要重新做吗 服务器能查到账号登录记录吗 数据库范式说法错误 查询数据库中以a开头的字符 毕业设计模板 网络技术
0