package com.zy.kingdee.utils;
|
|
public class SnowFlakeUtils {
|
private static SnowFlakeUtils flowIdWorker = new SnowFlakeUtils(1);
|
private final long id;
|
private final long epoch = 1524291141010L;
|
private final long workerIdBits = 10;
|
private final long maxWorkerId;
|
private final long sequenceBits = 12;
|
private final long workerIdShift;
|
private final long timestampLeftShift;
|
private final long sequenceMask;
|
private long sequence;
|
private long lastTimestamp;
|
|
private SnowFlakeUtils(long id) {
|
getClass();
|
this.maxWorkerId = (-1) ^ ((-1) << 10);
|
|
getClass();
|
this.workerIdShift = 12L;
|
getClass();
|
getClass();
|
this.timestampLeftShift = 12 + 10;
|
getClass();
|
this.sequenceMask = (-1) ^ ((-1) << 12);
|
this.sequence = 0L;
|
this.lastTimestamp = -1L;
|
if (id > this.maxWorkerId || id < 0) {
|
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", Long.valueOf(this.maxWorkerId)));
|
}
|
this.id = id;
|
}
|
|
public static SnowFlakeUtils getFlowIdInstance() {
|
return flowIdWorker;
|
}
|
|
private static long timeGen() {
|
return System.currentTimeMillis();
|
}
|
|
public static void main(String[] args) {
|
for (int i = 0; i < 10; i++) {
|
SnowFlakeUtils snowFlakeUtils = getFlowIdInstance();
|
System.out.println(snowFlakeUtils.nextId());
|
}
|
}
|
|
public synchronized long nextId() {
|
long timestamp = timeGen();
|
if (this.lastTimestamp == timestamp) {
|
this.sequence = (this.sequence + 1) & this.sequenceMask;
|
if (this.sequence == 0) {
|
timestamp = tilNextMillis(this.lastTimestamp);
|
}
|
} else {
|
this.sequence = 0L;
|
}
|
if (timestamp < this.lastTimestamp) {
|
return -1L;
|
}
|
this.lastTimestamp = timestamp;
|
getClass();
|
return ((timestamp - 1524291141010L) << ((int) this.timestampLeftShift)) | (this.id << ((int) this.workerIdShift)) | this.sequence;
|
}
|
|
private long tilNextMillis(long lastTimestamp) {
|
long jTimeGen = timeGen();
|
while (true) {
|
long timestamp = jTimeGen;
|
if (timestamp <= lastTimestamp) {
|
jTimeGen = timeGen();
|
} else {
|
return timestamp;
|
}
|
}
|
}
|
}
|