基于雪花算法实现的数据库唯一ID工具类
2023-12-15 11:40:24
package com.ideatech.ams.ucam.utils;
/**
* Created with IntelliJ IDEA.
* 用于生成唯一的数据库ID的工具类,基于雪花算法实现。
* <p>
* 雪花算法的特点:
* - 时间有序:生成的ID随时间递增,保证了ID的时序性。
* - 唯一性:在同一毫秒内生成的ID不会重复。
* - 分布式友好:适用于分布式系统,避免ID冲突。
* <p>
* 使用方式:
* 调用 generateUniqueId() 方法可以生成唯一的ID。
* <p>
* 注意事项:
* - 需要确保系统时钟不回退,以避免生成的ID不连续。
* - 在高并发情况下,需要测试生成的ID是否唯一。
*
* @author Gotham
* @date 2023/9/23 Time: 15:41
* Email: Gotham
*/
public class IdInitUtil {
private static final long EPOCH = 1632360000000L; // 设置一个起始时间戳(2021-09-24)
private static final long SEQUENCE_BITS = 12;
private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1;
private static final long SEQUENCE_SHIFT = 0;
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS;
private static final long MAX_SEQUENCE_NUMBER = 999L; // 每毫秒最多生成999个ID
private static long lastTimestamp = -1L;
private static long sequence = 0L;
/**
* 生成数据库唯一ID方法
*
* @return 唯一ID
* @throws RuntimeException 如果时钟回退或每毫秒生成的ID数量超过最大限制,将抛出异常
*/
public synchronized static long generateUniqueId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException("时钟回退异常");
}
if (currentTimestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
// 当前毫秒内生成的ID超过最大限制
currentTimestamp = waitUntilNextMillis(currentTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = currentTimestamp;
long id = ((currentTimestamp - EPOCH) << TIMESTAMP_SHIFT) | (sequence << SEQUENCE_SHIFT);
if (sequence > MAX_SEQUENCE_NUMBER) {
throw new RuntimeException("每毫秒生成的ID数量超过最大限制");
}
return id;
}
/**
* 生成数据库唯一ID方法
*
* @return 唯一ID
* @throws RuntimeException 如果时钟回退或每毫秒生成的ID数量超过最大限制,将抛出异常
*/
public synchronized static long generateNumber() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException("时钟回退异常");
}
if (currentTimestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
// 当前毫秒内生成的ID超过最大限制
currentTimestamp = waitUntilNextMillis(currentTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = currentTimestamp;
long id = ((currentTimestamp - EPOCH) << TIMESTAMP_SHIFT) | (sequence << SEQUENCE_SHIFT);
if (sequence > MAX_SEQUENCE_NUMBER) {
throw new RuntimeException("每毫秒生成的ID数量超过最大限制");
}
return id;
}
/**
* 在同一毫秒内等待,直到下一个毫秒
*
* @param currentTimestamp 当前时间戳
* @return 下一个毫秒的时间戳
*/
private static long waitUntilNextMillis(long currentTimestamp) {
while (currentTimestamp <= lastTimestamp) {
currentTimestamp = System.currentTimeMillis();
}
return currentTimestamp;
}
}
文章来源:https://blog.csdn.net/qq_37707251/article/details/135012525
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!