/**
* 雪花算法
*
* 生成全局唯一递增ID,共64位。0 -- 00000000 00000000 00000000 00000000 00000000 0 -- 00000 -- 00000 -- 000000000000
* 第一位表示符号,固定为0,41位表示毫秒时间戳,能用69年,5位表示数据中心ID,5位表示机器节点ID,12位表示同一毫秒内的序列号(4095个)
* @author fengyurong
* @date 2021-10-27 6:03 PM
*/
public class MySnowflake {
//基础毫秒级时间戳 2021-01-01 00:00:00
public static final long BASE_PERIOD = 1609430400000L;
//序列号掩码
public static final long SEQUENCE_MASK = -1L ^ (-1L << 12);
//机器节点偏移
public static final int WORK_ID_SHIFT = 12;
//数据中心偏移
public static final long DATA_CENTER_ID_SHIFT = WORK_ID_SHIFT + 5;
//毫秒时间戳偏移量
public static final long TIMESTAMP_SHIFT = DATA_CENTER_ID_SHIFT + 5;
//机器节点ID
public int workId;
//数据中心ID
public int dataCenterId;
//同一毫秒内序列号
public long sequence = 0L;
//上一次时间戳
public long lastTimeStamp;
public MySnowflake(int workId, int dataCenterId) {
this.workId = workId;
this.dataCenterId = dataCenterId;
}
public long genTime() {
return System.currentTimeMillis();
}
public synchronized long nextId() {
long timeStamp = this.genTime();
if(timeStamp <= lastTimeStamp) {
//能接受2秒内的时钟回拨
if(timeStamp - lastTimeStamp <= 2000) {
timeStamp = lastTimeStamp;
} else {
throw new RuntimeException("发生了时钟回拨");
}
}
if(timeStamp == lastTimeStamp) {
sequence = (sequence + 1) & SEQUENCE_MASK;
timeStamp = this.getNextMil(lastTimeStamp);
} else {
sequence = 0L;
}
lastTimeStamp = timeStamp;
return ((timeStamp - BASE_PERIOD) << TIMESTAMP_SHIFT) | (workId << WORK_ID_SHIFT) | (dataCenterId << DATA_CENTER_ID_SHIFT) | sequence;
}
/**
* 循环获取下一毫秒
* @return
*/
public long getNextMil(long lastTimeStamp) {
long timeStamp = this.genTime();
while(timeStamp == lastTimeStamp) {
timeStamp = this.genTime();
}
if (timeStamp < lastTimeStamp) {
throw new RuntimeException("发生了时钟回拨");
}
return timeStamp;
}
public static void main(String[] args) {
MySnowflake snowflake = new MySnowflake(1,2);
Set<Long> set = new HashSet<>();
for (int i = 0; i < 100000000; i++) {
long id = snowflake.nextId();
if(set.contains(id)) {
System.out.println(id);
}else {
set.add(id);
}
}
}
}
雪花算法
最新推荐文章于 2024-10-03 13:36:06 发布
该博客介绍了雪花算法的实现,这是一种用于生成全局唯一递增ID的算法。64位ID由符号位、41位毫秒时间戳、5位数据中心ID、5位机器节点ID和12位序列号组成。当遇到时钟回拨时,算法能够处理并避免冲突。示例代码展示了如何使用雪花算法生成ID。
摘要由CSDN通过智能技术生成