雪花算法是一种分布式唯一ID生成算法,通过对时间戳、工作节点ID和序列号进行位运算和组合,生成一个可排序且唯一的64位ID。
实现原理:
首先,我们需要定义算法中的参数:
在算法中,我们使用一个64位的long型变量来表示生成的唯一ID。其结构如下所示:
在生成唯一ID的过程中,需要注意以下几点:
最后,将时间戳、工作节点ID和序列号进行位运算和组合,生成最终的唯一ID。生成ID的过程可以保证在相同毫秒内、相同工作节点和序列号的情况下生成的ID是唯一的。
通过以上原理,雪花算法可以在分布式环境中生成大量唯一ID,并且保证ID的有序性和唯一性。在实际应用中,可以根据具体需求调整参数的位数,以满足不同场景下对ID的要求。
使用Java实现雪花算法生成16位数字的代码:
public class SnowflakeAlgorithm {
private long sequence = 0L;
private long lastTimestamp = -1L;
private final long workerIdBits = 5L;
private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
private final long sequenceBits = 10L;
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
private final long workerIdShift = sequenceBits;
private final long timestampLeftShift = sequenceBits + workerIdBits;
private final long twepoch = 1622505600000L;
private final long workerId;
public SnowflakeAlgorithm(long workerId) {
if (workerId < 0 || workerId > maxWorkerId) {
throw new IllegalArgumentException("Worker ID must be between 0 and " + maxWorkerId);
}
this.workerId = workerId;
}
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds.");
}
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
return ((timestamp - twepoch) << timestampLeftShift) |
(workerId << workerIdShift) |
sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
}
public class Main {
public static void main(String[] args) {
SnowflakeAlgorithm snowflake = new SnowflakeAlgorithm(1);
for (int i = 0; i < 10; i++) {
long id = snowflake.nextId();
System.out.println(id);
}
}
}