package com.core.common;
|
|
public class SnowflakeIdWorker {
|
|
private final long twepoch = 1420041600000L;
|
private final long sequenceBits = 12L;
|
private final long workerIdBits = 5L;
|
private final long datacenterIdBits = 5L;
|
private final long workerIdLeftShift = 12L;
|
private final long datacenterIdLeftShift = 17L;
|
private final long timestampLeftShift = 22L;
|
private final long maxWorkerId = 31L;
|
private final long maxDatacenterId = 31L;
|
private final long sequenceMask = 4095L;
|
|
private long workerId;
|
private long datacenterId;
|
private long sequence = 0L;
|
private long lastTimestamp = -1L;
|
|
public SnowflakeIdWorker(long workerId, long datacenterId) {
|
if (workerId > maxWorkerId || workerId < 0) {
|
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
|
}
|
if (datacenterId > maxDatacenterId || datacenterId < 0) {
|
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
|
}
|
this.workerId = workerId;
|
this.datacenterId = datacenterId;
|
}
|
|
public SnowflakeIdWorker() {
|
this(0L, 0L);
|
}
|
|
public synchronized long nextId() {
|
long timestamp = timeGen();
|
if (timestamp < lastTimestamp) {
|
throw new RuntimeException(String.format(
|
"Clock moved backwards. Refusing to generate id for %d milliseconds",
|
lastTimestamp - timestamp));
|
}
|
if (lastTimestamp == timestamp) {
|
sequence = (sequence + 1) & sequenceMask;
|
if (sequence == 0) {
|
timestamp = tilNextMillis(lastTimestamp);
|
}
|
} else {
|
sequence = 0L;
|
}
|
lastTimestamp = timestamp;
|
return ((timestamp - twepoch) << timestampLeftShift)
|
| (datacenterId << datacenterIdLeftShift)
|
| (workerId << workerIdLeftShift)
|
| sequence;
|
}
|
|
protected long tilNextMillis(long lastTimestamp) {
|
long timestamp = timeGen();
|
while (timestamp <= lastTimestamp) {
|
timestamp = timeGen();
|
}
|
return timestamp;
|
}
|
|
protected long timeGen() {
|
return System.currentTimeMillis();
|
}
|
|
public static void main(String[] args) {
|
SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0L, 0L);
|
for (int i = 0; i < 1000; i++) {
|
long id = idWorker.nextId();
|
System.out.println(Long.toBinaryString(id));
|
System.out.println(id);
|
}
|
}
|
}
|