package com.qianwen.core.sequence.sequence.impl;
|
|
import com.qianwen.core.sequence.exception.SeqException;
|
import com.qianwen.core.sequence.sequence.Sequence;
|
|
|
public class SnowflakeSequence implements Sequence {
|
private long workerId;
|
private long datacenterId;
|
private final long twepoch = 1514736000000L;
|
private final long workerIdBits = 5;
|
private final long datacenterIdBits = 5;
|
private final long maxWorkerId = 31;
|
private final long maxDatacenterId = 31;
|
private final long sequenceBits = 12;
|
private final long workerIdShift = 12;
|
private final long datacenterIdShift = 17;
|
private final long timestampLeftShift = 22;
|
private final long sequenceMask = 4095;
|
private long sequence = 0;
|
private long lastTimestamp = -1;
|
|
@Override // com.qianwen.core.sequence.sequence.Sequence
|
public synchronized long nextValue() throws SeqException {
|
long timestamp = timeGen();
|
if (timestamp < this.lastTimestamp) {
|
throw new SeqException("[SnowflakeSequence-nextValue] 当前时间小于上次生成序列号的时间,时间被回退了,请确认服务器时间的设置.");
|
}
|
if (this.lastTimestamp == timestamp) {
|
this.sequence = (this.sequence + 1) & 4095;
|
if (this.sequence == 0) {
|
timestamp = tilNextMillis(this.lastTimestamp);
|
}
|
} else {
|
this.sequence = 0L;
|
}
|
this.lastTimestamp = timestamp;
|
return ((timestamp - 1514736000000L) << 22) | (this.datacenterId << 17) | (this.workerId << 12) | this.sequence;
|
}
|
|
private long tilNextMillis(long lastTimestamp) {
|
long timeGen = timeGen();
|
while (true) {
|
long timestamp = timeGen;
|
if (timestamp <= lastTimestamp) {
|
timeGen = timeGen();
|
} else {
|
return timestamp;
|
}
|
}
|
}
|
|
private long timeGen() {
|
return System.currentTimeMillis();
|
}
|
|
public void setWorkerId(long workerId) {
|
if (workerId > 31) {
|
throw new SeqException("[SnowflakeSequence-setWorkerId] workerId 不能大于31.");
|
}
|
this.workerId = workerId;
|
}
|
|
public void setDatacenterId(long datacenterId) {
|
if (datacenterId > 31) {
|
throw new SeqException("[SnowflakeSequence-setDatacenterId] datacenterId 不能大于31.");
|
}
|
this.datacenterId = datacenterId;
|
}
|
|
@Override // com.qianwen.core.sequence.sequence.Sequence
|
public String nextNo() throws SeqException {
|
return String.valueOf(nextValue());
|
}
|
}
|