java 雪花算法生成9位id
时间: 2023-12-22 08:20:17 浏览: 175
雪花算法是一种分布式唯一 ID 生成算法,可以生成唯一的、有序的、可排序的、高并发的 ID。以下是 Java 实现的 9 位雪花算法生成 ID 的示例代码:
```java
public class SnowflakeIdGenerator {
private static final long START_STAMP = 1577808000000L; // 2020-01-01 00:00:00
private static final long SEQUENCE_BITS = 4L;
private static final long WORKER_ID_BITS = 5L;
private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
private volatile long lastTimestamp = -1L;
private volatile long sequence = 0L;
private final long workerId;
public SnowflakeIdGenerator(long workerId) {
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException("Worker ID must be between 0 and " + MAX_WORKER_ID);
}
this.workerId = workerId;
}
public synchronized long nextId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards! Refusing to generate ID");
}
if (currentTimestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
currentTimestamp = nextTimestamp(currentTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = currentTimestamp;
return ((currentTimestamp - START_STAMP) << TIMESTAMP_SHIFT) |
(workerId << WORKER_ID_SHIFT) |
sequence;
}
private long nextTimestamp(long currentTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= currentTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
}
```
此代码中,我们使用一个 long 类型的变量来表示生成的 ID,其中,前 41 位是时间戳(毫秒级),接着的 5 位是机器 ID,最后的 4 位是序列号。根据雪花算法的规则,序列号是每毫秒内的计数器,最大值为 15,超过则等待下一毫秒再生成 ID。
使用此类生成 9 位 ID,我们可以将机器 ID 的位数减少为 4,序列号的位数减少为 1,时间戳的起点可以设为 2020-01-01 00:00:00,代码如下:
```java
public class NineDigitsSnowflakeIdGenerator {
private static final long START_STAMP = 1577808000000L; // 2020-01-01 00:00:00
private static final long SEQUENCE_BITS = 1L;
private static final long WORKER_ID_BITS = 4L;
private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
private volatile long lastTimestamp = -1L;
private volatile long sequence = 0L;
private final long workerId;
public NineDigitsSnowflakeIdGenerator(long workerId) {
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException("Worker ID must be between 0 and " + MAX_WORKER_ID);
}
this.workerId = workerId;
}
public synchronized long nextId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards! Refusing to generate ID");
}
if (currentTimestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
currentTimestamp = nextTimestamp(currentTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = currentTimestamp;
return ((currentTimestamp - START_STAMP) << TIMESTAMP_SHIFT) |
(workerId << WORKER_ID_SHIFT) |
sequence;
}
private long nextTimestamp(long currentTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= currentTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
}
```
阅读全文