雪花算法程序实现及史上最全解析

简介: 雪花算法实现及介绍 (生产可以直接使用)
importorg.junit.Test;
importorg.junit.runner.RunWith;
importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/*** @author 86182* @date 2023/6/5 15:49* @desc*/publicclassSnowFlakeDemo {
/**起始的时间戳,用于计算时间戳部分*/privatefinalstaticlongSTART_STMP=1480166465631L;
/**序列号占用的位数*/privatefinalstaticlongSEQUENCE_BIT=12;
/**机器标识占用的位数 */privatefinalstaticlongMACHINE_BIT=5;
/**数据中心占用的位数 */privatefinalstaticlongDATA_CENTER_BIT=5;
/**数据中心最大值*//*** 这个运算`-1L ^ (-1L << DATA_CENTER_BIT)`的含义是:* - -1L << DATA_CENTER_BIT是将-1的二进制表示向左移动DATA_CENTER_BIT位,也就是5位。* - 由于-1的二进制表示是除了最高位都是1,向左移动5位后,低5位是1,高位都是0。* - 然后使用`^`运算,即异或运算对-1和向左移动的结果进行运算。* - 由于异或运算遵循交换律和结合律,且异或相同为0,不同为1。* - 所以,最终得到的结果是高5位是1,低位都是0,也就是一个5位的二进制数,其十进制结果就是2^5 - 1 = 31。* 所以,简单来说,该运算的结果是获取一个位数为DATA_CENTER_BIT的二进制数,并将其转换为十进制 - 这里就是31。*/privatefinalstaticlongMAX_DATA_CENTER_NUM=-1L^ (-1L<<DATA_CENTER_BIT);
/**机器标识最大值*/privatefinalstaticlongMAX_MACHINE_NUM=-1L^ (-1L<<MACHINE_BIT);
/**序列号最大值*/privatefinalstaticlongMAX_SEQUENCE=-1L^ (-1L<<SEQUENCE_BIT);
/**机器标识左移位数,12位*/privatefinalstaticlongMACHINE_LEFT=SEQUENCE_BIT;
/**数据中心左移位数,12+5=17位*/privatefinalstaticlongDATA_CENTER_LEFT=SEQUENCE_BIT+MACHINE_BIT;
/**时间戳左移位数,12+5+5=22位*/privatefinalstaticlongTIMESTMP_LEFT=DATA_CENTER_LEFT+DATA_CENTER_BIT;
/**数据中心ID*/privatelongdataCenterId;
/**机器标识ID*/privatelongmachineId;
/**序列号 (备注:对于并发度不高的系统而言,此序列号始终是0,生成的雪花Id末尾一位数字始终为偶数!!!)*/privatelongsequence=0L;
/**上一次时间戳*/privatelonglastStmp=-1L;
publicSnowFlakeDemo(){}
publicSnowFlakeDemo(longdataCenterId, longmachineId) {
/**检验数据中心ID和机器ID合法性,不合法抛出异常*/if (dataCenterId>MAX_DATA_CENTER_NUM||dataCenterId<0) {
thrownewIllegalArgumentException("dataCenterId can't be greater than MAX_DATA_CENTER_NUM or less than 0");
        }
if (machineId>MAX_MACHINE_NUM||machineId<0) {
thrownewIllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
        }
/**合法的情况下将参数赋值给类成员变量*/this.dataCenterId=dataCenterId;
this.machineId=machineId;
    }
/**产生下一个ID*/publicsynchronizedlongnextId() {
/**获取当前时间戳,毫秒级*/longcurrStmp=getNewstmp();
/**时间戳回拨,抛出异常*/if (currStmp<lastStmp) {
thrownewRuntimeException("Clock moved backwards.  Refusing to generate id");
        }
/**如果时间戳与上一次相同,序列号自增*/if (currStmp==lastStmp) {
/*** (sequence + 1) & MAX_SEQUENCE 的含义是:* 1. sequence + 1 首先将序列号sequence增加1。* 2. & MAX_SEQUENCE 然后与序列号最大值MAX_SEQUENCE进行与运算。* 3. 由于与运算遵循交换律和结合律,且相同为1,不同为0。* 4. 所以,如果sequence增加后的值没有超过MAX_SEQUENCE,则与运算结果不变,sequence增加后的值仍然保留。* 5. 但如果sequence增加后的值超过了MAX_SEQUENCE,则与运算会将超出的高位全部抹去,只保留低MAX_SEQUENCE位,使得sequence不会超过该最大值。* 所以,该运算的效果是,每次让sequence增加1,但sequence增加后的值不会超过我们设置的MAX_SEQUENCE最大值,一旦超过,高位会被抹去,重新回到低MAX_SEQUENCE位。*/sequence= (sequence+1) &MAX_SEQUENCE;
/**同一毫秒序列号已经最大,等待下一毫秒*/if (sequence==0L) {
currStmp=getNextMill();
            }
        } else {
/**不同毫秒序列号置为0,从0开始*/sequence=0L;
        }
/**更新时间戳为当前时间戳*/lastStmp=currStmp;
/*** 计算ID* 时间戳部分(41 bit)*     数据中心部分(5 bit)*         机器标识部分(5 bit)*             序列号部分(12 bit)*//*** 含义是:* 1. (currStmp - START_STMP) << TIMESTMP_LEFT 首先计算出当前时间戳currStmp减去起始时间戳START_STMP的差值,然后将该差值向左移动TIMESTMP_LEFT位,也就是41位。这步骤生成时间戳部分。* 2. | dataCenterId << DATA_CENTER_LEFT  将数据中心ID向左移动DATA_CENTER_LEFT位,也就是17位,然后使用按位或|运算符将该结果与1步骤的结果进行|运算。这步骤在时间戳部分的基础上添加了数据中心ID部分。* 3. | machineId << MACHINE_LEFT 将机器ID向左移动MACHINE_LEFT位,也就是22位,然后使用按位或运算符将该结果与2步骤的结果进行|运算。这步骤在时间戳部分和数据中心ID部分的基础上添加了机器ID部分。* 4. | sequence 最后,直接使用按位或运算符将序列号sequence与3步骤的结果进行|运算,添加序列号部分,得到最终完整的ID。* 5. 通过这4步运算,我们按照时间戳→数据中心ID→机器ID→序列号的顺序,一步步构建完整的ID。这与雪花ID的结构与顺序是一致的。* 所以,这句运算的含义就是按照部分→部分的方式构建完整的雪花ID,每一步都使用按位或运算,这是一种高效的ID构建方式。这是雪花算法实现的关键所在。*/return (currStmp-START_STMP) <<TIMESTMP_LEFT|dataCenterId<<DATA_CENTER_LEFT|machineId<<MACHINE_LEFT|sequence;
    }
/*** 等待下一毫秒** @return*/privatelonggetNextMill() {
longmill=getNewstmp();
while (mill<=lastStmp) {
mill=getNewstmp();
        }
returnmill;
    }
/*** 获取当前时间戳,毫秒级* @return*/privatelonggetNewstmp() {
returnSystem.currentTimeMillis();
    }
}


相关文章
|
27天前
|
机器学习/深度学习 存储 算法
如何评判算法好坏?复杂度深度解析
如何评判算法好坏?复杂度深度解析
24 0
|
30天前
|
机器学习/深度学习 算法 PyTorch
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
223 1
|
29天前
|
缓存 算法 C语言
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
46 0
|
16天前
|
存储 缓存 算法
深度解析JVM世界:垃圾判断和垃圾回收算法
深度解析JVM世界:垃圾判断和垃圾回收算法
|
17天前
|
存储 算法
【算法与数据结构】深入解析二叉树(二)之堆结构实现
【算法与数据结构】深入解析二叉树(二)之堆结构实现
|
22天前
|
存储 算法
从动态规划到贪心算法:最长递增子序列问题的方法全解析
从动态规划到贪心算法:最长递增子序列问题的方法全解析
20 2
|
26天前
|
缓存 算法 关系型数据库
深度思考:雪花算法snowflake分布式id生成原理详解
雪花算法snowflake是一种优秀的分布式ID生成方案,其优点突出:它能生成全局唯一且递增的ID,确保了数据的一致性和准确性;同时,该算法灵活性强,可自定义各部分bit位,满足不同业务场景的需求;此外,雪花算法生成ID的速度快,效率高,能有效应对高并发场景,是分布式系统中不可或缺的组件。
深度思考:雪花算法snowflake分布式id生成原理详解
|
1月前
|
算法 数据库 索引
什么是雪花算法?啥原理?
什么是雪花算法?啥原理?
34 0
什么是雪花算法?啥原理?
|
8天前
yolo-world 源码解析(六)(2)
yolo-world 源码解析(六)
18 0
|
8天前
yolo-world 源码解析(六)(1)
yolo-world 源码解析(六)
12 0

推荐镜像

更多