
top.bluesword.util.sequence.Snowflake Maven / Gradle / Ivy
The newest version!
package top.bluesword.util.sequence;
import top.bluesword.util.exception.SwordRuntimeException;
/**
* 基于Twitter的SnowFlake算法的ID生成工具
*
* @author 李林峰
*/
public class Snowflake {
/**
* 起始时间戳,用于用当前时间戳减去这个时间戳,算出偏移量
**/
private static final long START_TIME = 1530258005750L;
private long workerIdShift;
private long dataCenterIdShift;
private long timestampLeftShift;
private long sequenceMask;
private long workerId;
private long dataCenterId;
private long sequence = 0L;
private long lastTimestamp = -1L;
/**
* 基于Snowflake创建分布式ID生成器
*/
public Snowflake() {
this(12L);
}
/**
* @param sequenceBits 序列号二进制位数
*/
public Snowflake(long sequenceBits) {
this(0L, 0L, sequenceBits, 0L, 0L);
}
/**
* @param dataCenterId 数据中心ID
* @param workerId 机器ID
*/
public Snowflake(long dataCenterId, long workerId) {
this(5L, 5L, 12L, dataCenterId, workerId);
}
/**
* @param workerIdBits 机器ID二进制位数
* @param dataCenterIdBits 数据中心ID二进制位数
* @param sequenceBits 序列号二进制位数
* @param dataCenterId 数据中心ID
* @param workerId 机器ID
*/
public Snowflake(long workerIdBits, long dataCenterIdBits, long sequenceBits, long dataCenterId, long workerId) {
long maxDataCenterId = ~(-1L << dataCenterIdBits);
if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
throw new SwordRuntimeException(String.format("数据中心ID不可以大于 %d 或小于 0", maxDataCenterId));
}
long maxWorkerId = ~(-1L << workerIdBits);
if (workerId > maxWorkerId || workerId < 0) {
throw new SwordRuntimeException(String.format("工作机器ID不可以大于 %d 或小于 0", maxWorkerId));
}
this.dataCenterId = dataCenterId;
this.workerId = workerId;
this.sequenceMask = ~(-1L << sequenceBits);
this.workerIdShift = sequenceBits;
this.dataCenterIdShift = sequenceBits + workerIdBits;
this.timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;
}
/**
* 获取ID
* @return ID
*/
public synchronized Long nextId() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) {
throw new SwordRuntimeException(String.format("时间回退,请在 %d 毫秒后申请ID",lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
//通过位与运算保证计算的结果在范围内
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = this.tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
return ((timestamp - START_TIME) << timestampLeftShift) | (dataCenterId << dataCenterIdShift)
| (workerId << workerIdShift) | sequence;
}
/**
* 保证返回的毫秒数在参数之后(阻塞到下一个毫秒,直到获得新的时间戳)
*/
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy