千家信息网

如何编写Java的雪花算法代码

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,本篇内容介绍了"如何编写Java的雪花算法代码"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!pack
千家信息网最后更新 2025年11月07日如何编写Java的雪花算法代码

本篇内容介绍了"如何编写Java的雪花算法代码"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

package com.java265.other;public class Test {    // 因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。    // 机器ID 2进制5位 32位减掉1位 31个    private long workerId;    // 机房ID 2进制5位 32位减掉1位 31个    private long datacenterId;    // 代表一毫秒内生成的多个id的最新序号 12位 4096 -1 = 4095 个    private long sequence;    // 设置一个时间初始值 2^41 - 1 差不多可以用69年    private long twepoch = 1585644268888L;    // 5位的机器id    private long workerIdBits = 5L;    // 5位的机房id    private long datacenterIdBits = 5L;    // 每毫秒内产生的id数 2 的 12次方    private long sequenceBits = 12L;    // 这个是二进制运算,就是5 bit最多只能有31个数字,也就是说机器id最多只能是32以内    private long maxWorkerId = -1L ^ (-1L << workerIdBits);    // 这个是一个意思,就是5 bit最多只能有31个数字,机房id最多只能是32以内    private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);    private long workerIdShift = sequenceBits;    private long datacenterIdShift = sequenceBits + workerIdBits;    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;    private long sequenceMask = -1L ^ (-1L << sequenceBits);    // 记录产生时间毫秒数,判断是否是同1毫秒    private long lastTimestamp = -1L;    public long getWorkerId() {        return workerId;    }    public long getDatacenterId() {        return datacenterId;    }    public long getTimestamp() {        return System.currentTimeMillis();    }    public Test(long workerId, long datacenterId, long sequence) {        // 检查机房id和机器id是否超过31 不能小于0        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));        }        this.workerId = workerId;        this.datacenterId = datacenterId;        this.sequence = sequence;    }    // 这个是核心方法,通过调用nextId()方法,让当前这台机器上的snowflake算法程序生成一个全局唯一的id    public 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));        }        // 下面是说假设在同一个毫秒内,又发送了一个请求生成一个id        // 这个时候就得把seqence序号给递增1,最多就是4096        if (lastTimestamp == timestamp) {            // 这个意思是说一个毫秒内最多只能有4096个数字,无论你传递多少进来,            // 这个位运算保证始终就是在4096这个范围内,避免你自己传递个sequence超过了4096这个范围            sequence = (sequence + 1) & sequenceMask;            // 当某一毫秒的时间,产生的id数 超过4095,系统会进入等待,直到下一毫秒,系统继续产生ID            if (sequence == 0) {                timestamp = tilNextMillis(lastTimestamp);            }        } else {            sequence = 0;        }        // 这儿记录一下最近一次生成id的时间戳,单位是毫秒        lastTimestamp = timestamp;        // 这儿就是最核心的二进制位运算操作,生成一个64bit的id        // 先将当前时间戳左移,放到41 bit那儿;将机房id左移放到5 bit那儿;将机器id左移放到5 bit那儿;将序号放最后12 bit        // 最后拼接起来成一个64 bit的二进制数字,转换成10进制就是个long型        return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift)                | (workerId << workerIdShift) | sequence;    }    /**     * 当某一毫秒的时间,产生的id数 超过4095,系统会进入等待,直到下一毫秒,系统继续产生ID     *      * @param lastTimestamp     * @return     */    private long tilNextMillis(long lastTimestamp) {        long timestamp = timeGen();        while (timestamp <= lastTimestamp) {            timestamp = timeGen();        }        return timestamp;    }    // 获取当前时间戳    private long timeGen() {        return System.currentTimeMillis();    }    /**     * main 测试类     *      * @param args     */    public static void main(String[] args) {        System.out.println(1 & 4596);        System.out.println(2 & 4596);        System.out.println(6 & 4596);        System.out.println(6 & 4596);        System.out.println(6 & 4596);        System.out.println(6 & 4596);        Test test = new Test(1, 1, 1);        for (int i = 0; i < 22; i++) {            System.out.println(test.nextId());        }    }}

"如何编写Java的雪花算法代码"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

就是 时间 生成 机器 二进制 数字 机房 系统 算法 序号 进制 运算 代码 雪花 内容 单位 意思 方法 更多 核心 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 福州智慧校园软件开发 小规模软件开发企业增值税率 新潮软件开发济南 国家安全部网络安全保卫局 pve服务器能去对方城市吗 黑龙江省游戏软件开发 软件开发需要报什么科 长沙学习软件开发公司哪家强 菏泽市编委数据库 浙江调度服务器厂家虚拟主机 嵌入式现场管理服务器价格 数据库中修改库 服务器批量远程桌面 网络安全是一个人独立的权利 网络安全之webshell 安徽通信软件开发品质保障 有线网络安全性的特点 县级网络安全风险点 数据库安全防护魔力象限 服务器 假死 高级软件开发工程师济南工资水平 网络技术专业好考么 通州回收二手服务器多少钱 软件开发程度度量规范 我的世界服务器修改人数上限 知道ip如何知道用的什么服务器 提倡清朗网络安全的征文 广东嵌入式软件开发哪家好 计算机软件开发要敲代码吗 支付宝扫脸支付软件开发
0