雪花算法
public class SnowflakeIdGenerator {
private static final int BITS_SEQUENCE = 12;
private static final int BITS_MACHINE_ID = 5;
private static final int BITS_DATACENTER_ID = 5;
private static final int SEQUENCE_MASK = (1 << BITS_SEQUENCE) - 1;
private static final int MAX_MACHINE_ID = (1 << BITS_MACHINE_ID) - 1;
private static final int MAX_DATACENTER_ID = (1 << BITS_DATACENTER_ID) - 1;
private final int datacenterId;
private final int machineId;
private long lastTimestamp = -1;
private int sequence = 0;
public SnowflakeIdGenerator(int datacenterId, int machineId) {
if (datacenterId < 0 || datacenterId > MAX_DATACENTER_ID) {
throw new IllegalArgumentException("Invalid datacenter ID");
}
if (machineId < 0 || machineId > MAX_MACHINE_ID) {
throw new IllegalArgumentException("Invalid machine ID");
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
public synchronized long nextId() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards!");
}
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & SEQUENCE_MASK;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0;
}
lastTimestamp = timestamp;
long id = ((timestamp - 1288834974657L) << (BITS_SEQUENCE + BITS_MACHINE_ID + BITS_DATACENTER_ID));
id |= (datacenterId << (BITS_MACHINE_ID + BITS_SEQUENCE));
id |= (machineId << BITS_SEQUENCE);
id |= sequence;
return id;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
}
Q.E.D.