1.引入pom依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.6.5</version>
</dependency>
2.源码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package cn.hutool.core.lang;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.util.StrUtil;
import java.io.Serializable;
import java.util.Date;
public class Snowflake implements Serializable {
private static final long serialVersionUID = 1L;
private final long twepoch;
private final long workerIdBits;
private final long maxWorkerId;
private final long dataCenterIdBits;
private final long maxDataCenterId;
private final long sequenceBits;
private final long workerIdShift;
private final long dataCenterIdShift;
private final long timestampLeftShift;
private final long sequenceMask;
private final long workerId;
private final long dataCenterId;
private final boolean useSystemClock;
private long sequence;//序列号
private long lastTimestamp; //上一次时间戳
public Snowflake(long workerId, long dataCenterId) {
this(workerId, dataCenterId, false);
}
public Snowflake(long workerId, long dataCenterId, boolean isUseSystemClock) {
this((Date)null, workerId, dataCenterId, isUseSystemClock);
}
public Snowflake(Date epochDate, long workerId, long dataCenterId, boolean isUseSystemClock) {
this.workerIdBits = 5L;
this.maxWorkerId = 31L;
this.dataCenterIdBits = 5L;
this.maxDataCenterId = 31L;
this.sequenceBits = 12L;
this.workerIdShift = 12L;
this.dataCenterIdShift = 17L;
this.timestampLeftShift = 22L;
this.sequenceMask = 4095L;
this.sequence = 0L;
this.lastTimestamp = -1L;
if (null != epochDate) {
this.twepoch = epochDate.getTime();
} else {
this.twepoch = 1288834974657L;
}
if (workerId <= 31L && workerId >= 0L) {
if (dataCenterId <= 31L && dataCenterId >= 0L) {
this.workerId = workerId;
this.dataCenterId = dataCenterId;
this.useSystemClock = isUseSystemClock;
} else {
throw new IllegalArgumentException(StrUtil.format("datacenter Id can't be greater than {} or less than 0", new Object[]{31L}));
}
} else {
throw new IllegalArgumentException(StrUtil.format("worker Id can't be greater than {} or less than 0", new Object[]{31L}));
}
}
public long getWorkerId(long id) {
return id >> 12 & 31L;
}
public long getDataCenterId(long id) {
return id >> 17 & 31L;
}
public long getGenerateDateTime(long id) {
return (id >> 22 & 2199023255551L) + this.twepoch;
}
/**
* 生成id
*/
public synchronized long nextId() {
long timestamp = this.genTime();
//当前时间小如传入时间报错 拒绝生成id
if (timestamp < this.lastTimestamp) {
if (this.lastTimestamp - timestamp >= 2000L) {
throw new IllegalStateException(StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", new Object[]{this.lastTimestamp - timestamp}));
}
timestamp = this.lastTimestamp;
}
//相同毫秒内,序列号自增
if (timestamp == this.lastTimestamp) {
long sequence = this.sequence + 1L & 4095L;
//同一毫秒的序列数已经达到最大
if (sequence == 0L) {
timestamp = this.tilNextMillis(this.lastTimestamp);
}
this.sequence = sequence;
} else {
//不同毫秒内,序列号设置为0
this.sequence = 0L;
}
this.lastTimestamp = timestamp;
return timestamp - this.twepoch << 22 //时间戳部分,占41位 左移22位
| this.dataCenterId << 17 //数据中心部分占5位,左移17位
| this.workerId << 12 //机器标识部分占5位,左移10位
| this.sequence; //序列号部分占12位
}
public String nextIdStr() {
return Long.toString(this.nextId());
}
private long tilNextMillis(long lastTimestamp) {
long timestamp;
for(timestamp = this.genTime(); timestamp == lastTimestamp; timestamp = this.genTime()) {
}
if (timestamp < lastTimestamp) {
throw new IllegalStateException(StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", new Object[]{lastTimestamp - timestamp}));
} else {
return timestamp;
}
}
private long genTime() {
return this.useSystemClock ? SystemClock.now() : System.currentTimeMillis();
}
}
3. 注入 使用
@Service
@Slf4j
public class XxxServiceImpl implements XxxServive {
@Autowired
private Snowflake snowflake;
public AxxRspDTO save(AxxReqDTO reqDTO) {
//获取Long类型id
Long id = snowflake.nextId();
//获取sring类型id
String id = snowflake.nextIdStr();
}
}
4优缺点:
1.优点:
毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。
可以根据自身业务特性分配bit位,非常灵活。
2.缺点:
依赖机器时钟,如果机器时钟回拨,会导致重复ID生成
在单机上是递增的,但是由于设计到分布式环境,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况
(此缺点可以认为无所谓,一般分布式ID只要求趋势递增,并不会严格要求递增,90%的需求都只要求趋势递增)
文章来源地址https://www.toymoban.com/news/detail-619986.html
文章来源:https://www.toymoban.com/news/detail-619986.html
到了这里,关于hutool工具包 中的雪花算法Snowflake 获取Long类型id 或者String 类型id(全局唯一id解决方案)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!