雪花算法(Snowflake)是一种分布式系统中生成唯一ID的算法,由Twitter开源。它生成的ID是一个64位的整数,通常表示为长整型(long)。为了生成一个16位的ID,我们可以将64位的雪花算法进行适当的调整。
以下是一个简化的16位雪花算法实现:
```java public class SnowflakeIdGenerator { private static final long START_TIMESTAMP = 1609459200000L; // 2021-01-01 00:00:00 private static final long MACHINE_ID_BITS = 4L; private static final long SEQUENCE_BITS = 12L;
private static final long MAX_MACHINE_ID = (1L << MACHINE_ID_BITS) - 1;
private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1;
private static final long MACHINE_ID_SHIFT = SEQUENCE_BITS;
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS;
private long machineId;
private long sequence = 0L;
private long lastTimestamp = -1L;
public SnowflakeIdGenerator(long machineId) {
if (machineId < 0 || machineId > MAX_MACHINE_ID) {
throw new IllegalArgumentException("Machine ID must be between 0 and " + MAX_MACHINE_ID);
}
this.machineId = machineId;
}
public synchronized long nextId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - currentTimestamp) + " milliseconds");
}
if (currentTimestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
currentTimestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = currentTimestamp;
return ((currentTimestamp - START_TIMESTAMP) << TIMESTAMP_SHIFT) |
(machineId << MACHINE_ID_SHIFT) |
sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
public static void main(String[] args) {
SnowflakeIdGenerator generator = new SnowflakeIdGenerator(1);
for (int i = 0; i < 10; i++) {
System.out.println(generator.nextId());
}
}
} ```
解释
- START_TIMESTAMP: 定义一个起始时间戳,用于计算相对时间戳。
- MACHINE_ID_BITS 和 SEQUENCE_BITS: 分别定义机器ID和序列号的位数。
- MAX_MACHINE_ID 和 MAX_SEQUENCE: 定义机器ID和序列号的最大值。
- MACHINE_ID_SHIFT 和 TIMESTAMP_SHIFT: 定义机器ID和序列号在64位中的偏移量。
- nextId(): 生成唯一ID的方法,包括时间戳、机器ID和序列号的组合。
使用方法
- 创建一个
SnowflakeIdGenerator
实例,传入机器ID(1表示示例)。 - 调用
nextId()
方法生成16位的ID。
这个实现确保了在分布式系统中生成的ID是唯一的,并且具有时间顺序性。