Files
FrameTour-BE/src/main/java/com/ycwl/basic/utils/SnowFlakeUtil.java
2025-05-30 17:25:28 +08:00

139 lines
3.9 KiB
Java

package com.ycwl.basic.utils;
import com.ycwl.basic.model.snowFlake.UniqueId;
import com.ycwl.basic.model.snowFlake.UniqueIdMetaData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author Created by liuhongguang
* @Description
*/
@Slf4j
@Component
public class SnowFlakeUtil {
/**
* 记录上一毫秒数
*/
private static long lastTimestamp = -1L;
/**
* 记录毫秒内的序列,0-4095
*/
private static long sequence = 0L;
private static Long machineId = 1L;
private static Long datacenterId =1L;
public static synchronized String getId() {
long timestamp = System.currentTimeMillis();
// 如果当前时间小于上一次ID生成的时间戳,说明系统时钟被修改过,回退在上一次ID生成时间之前应当抛出异常!!!
if (timestamp < lastTimestamp) {
throw new IllegalStateException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
//如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & UniqueIdMetaData.SEQUENCE_MASK;
//毫秒内序列溢出
if (sequence == 0) {
//阻塞到下一个毫秒,获得新的时间戳
timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return String.valueOf(timestamp);
}
}
//时间戳改变,毫秒内序列重置
else {
sequence = 0L;
}
// 上次生成ID的时间截
lastTimestamp = timestamp;
// 移位并通过或运算组成64位ID
return String.valueOf(((timestamp - UniqueIdMetaData.START_TIME) << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS)
| (datacenterId << UniqueIdMetaData.DATACENTER_SHIFT_BITS)
| (machineId<< UniqueIdMetaData.MACHINE_SHIFT_BITS)
| sequence);
}
public static Long getLongId(){
return Long.valueOf(getId());
}
public UniqueId explainId(long id) {
UniqueId uniqueId = com.ycwl.basic.utils.SnowFlakeUtil.convert(id);
if (uniqueId == null) {
log.error("==> 解析ID失败, ID不合法");
return null;
}
return uniqueId;
}
public Date transTime(long time) {
return new Date(time + UniqueIdMetaData.START_TIME);
}
/**
* 唯一ID对象解析返回ID
*
* @param uniqueId
* @return
*/
public static long convert(UniqueId uniqueId) {
long result = 0;
try {
result |= uniqueId.getSequence();
result |= uniqueId.getMachineId() << UniqueIdMetaData.MACHINE_SHIFT_BITS;
result |= uniqueId.getDatacenterId() << UniqueIdMetaData.DATACENTER_SHIFT_BITS;
result |= uniqueId.getTimestamp() << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS;
} catch (Exception e) {
e.printStackTrace();
return result;
}
return result;
}
public static UniqueId convert(long id) {
UniqueId uniqueId = null;
try {
uniqueId = new UniqueId();
uniqueId.setSequence(id & UniqueIdMetaData.SEQUENCE_MASK);
uniqueId.setMachineId((id >>> UniqueIdMetaData.MACHINE_SHIFT_BITS) & UniqueIdMetaData.MACHINE_MASK);
uniqueId.setDatacenterId((id >>> UniqueIdMetaData.DATACENTER_SHIFT_BITS) & UniqueIdMetaData.DATACENTER_MASK);
uniqueId.setTimestamp((id >>> UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS) & UniqueIdMetaData.TIMESTAMP_MASK);
} catch (Exception e) {
e.printStackTrace();
return uniqueId;
}
return uniqueId;
}
}