百度雪花算法 java代码实现
时间: 2023-09-04 20:01:26 浏览: 65
百度雪花算法是一种用来生成分布式唯一ID的算法,它保证在同一毫秒内不会生成重复的ID,并能在分布式系统中保证唯一性。在Java中,可以通过以下代码实现百度雪花算法:
```java
public class SnowflakeIdGenerator {
// 开始时间戳,默认为2010-01-01
private final long START_TIMESTAMP = 1262275200000L;
// 机器ID所占的位数
private final long WORKER_ID_BITS = 5L;
// 数据中心ID所占的位数
private final long DATA_CENTER_ID_BITS = 5L;
// 毫秒内自增序列所占的位数
private final long SEQUENCE_BITS = 12L;
// 最大机器ID
private final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
// 最大数据中心ID
private final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);
// 机器ID向左移的位数
private final long WORKER_ID_SHIFT = SEQUENCE_BITS;
// 数据中心ID向左移的位数
private final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
// 时间戳向左移的位数
private final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS;
// 序列号的最大值
private final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);
// 工作节点ID
private long workerId;
// 数据中心ID
private long dataCenterId;
// 当前毫秒内序列号
private long sequence = 0L;
// 上次生成ID的时间戳
private long lastTimestamp = -1L;
public SnowflakeIdGenerator(long workerId, long dataCenterId) {
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException("Worker ID超出范围");
}
if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {
throw new IllegalArgumentException("DataCenter ID超出范围");
}
this.workerId = workerId;
this.dataCenterId = dataCenterId;
}
public synchronized long generateId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException("系统时钟回退");
}
// 如果同一毫秒内生成过ID,则进行序列号+1
if (currentTimestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
// 当前毫秒内序列号已达到最大值,等待下一毫秒生成ID
if (sequence == 0) {
currentTimestamp = waitNextMillis(lastTimestamp);
}
} else {
// 不同毫秒内序列号重置为0
sequence = 0L;
}
lastTimestamp = currentTimestamp;
return ((currentTimestamp - START_TIMESTAMP) << TIMESTAMP_SHIFT)
| (dataCenterId << DATA_CENTER_ID_SHIFT)
| (workerId << WORKER_ID_SHIFT)
| sequence;
}
private long waitNextMillis(long lastTimestamp) {
long currentTimestamp = System.currentTimeMillis();
while (currentTimestamp <= lastTimestamp) {
currentTimestamp = System.currentTimeMillis();
}
return currentTimestamp;
}
}
```
使用这个SnowflakeIdGenerator类,可以创建一个实例,并调用`generateId()`方法来生成唯一ID。例如:
```java
SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(workerId, dataCenterId);
long id = idGenerator.generateId();
```