mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-24 18:04:54 +08:00
fix code
This commit is contained in:
parent
1ff0dcde0f
commit
5bf7dcf88e
@ -15,7 +15,6 @@ package org.dromara.hutool.core.data.id;
|
||||
import org.dromara.hutool.core.date.SystemClock;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.lang.tuple.Pair;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.RandomUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -53,11 +52,6 @@ public class Snowflake implements Serializable {
|
||||
* 默认的起始时间,为Thu, 04 Nov 2010 01:42:54 GMT
|
||||
*/
|
||||
public static long DEFAULT_TWEPOCH = 1288834974657L;
|
||||
/**
|
||||
* 默认回拨时间,2S
|
||||
*/
|
||||
public static long DEFAULT_TIME_OFFSET = 2000L;
|
||||
|
||||
private static final long WORKER_ID_BITS = 5L;
|
||||
// 最大支持机器节点数0~31,一共32个
|
||||
@SuppressWarnings({"PointlessBitwiseExpression", "FieldCanBeLocal"})
|
||||
@ -84,10 +78,6 @@ public class Snowflake implements Serializable {
|
||||
private final long workerId;
|
||||
private final long dataCenterId;
|
||||
private final boolean useSystemClock;
|
||||
/**
|
||||
* 允许的时钟回拨毫秒数
|
||||
*/
|
||||
private final long timeOffset;
|
||||
/**
|
||||
* 当在低频模式下时,序号始终为0,导致生成ID始终为偶数<br>
|
||||
* 此属性用于限定一个随机上限,在不同毫秒下生成序号时,给定一个随机数,避免偶数问题。<br>
|
||||
@ -146,20 +136,9 @@ public class Snowflake implements Serializable {
|
||||
* @param isUseSystemClock 是否使用{@link SystemClock} 获取当前时间戳
|
||||
* @since 5.1.3
|
||||
*/
|
||||
public Snowflake(final Date epochDate, final long workerId, final long dataCenterId, final boolean isUseSystemClock) {
|
||||
this(epochDate, workerId, dataCenterId, isUseSystemClock, DEFAULT_TIME_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param epochDate 初始化时间起点(null表示默认起始日期),后期修改会导致id重复,如果要修改连workerId dataCenterId,慎用
|
||||
* @param workerId 工作机器节点id
|
||||
* @param dataCenterId 数据中心id
|
||||
* @param isUseSystemClock 是否使用{@link SystemClock} 获取当前时间戳
|
||||
* @param timeOffset 允许时间回拨的毫秒数
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public Snowflake(final Date epochDate, final long workerId, final long dataCenterId, final boolean isUseSystemClock, final long timeOffset) {
|
||||
this(epochDate, workerId, dataCenterId, isUseSystemClock, timeOffset, 0);
|
||||
public Snowflake(final Date epochDate, final long workerId, final long dataCenterId,
|
||||
final boolean isUseSystemClock) {
|
||||
this(epochDate, workerId, dataCenterId, isUseSystemClock, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,17 +146,15 @@ public class Snowflake implements Serializable {
|
||||
* @param workerId 工作机器节点id
|
||||
* @param dataCenterId 数据中心id
|
||||
* @param isUseSystemClock 是否使用{@link SystemClock} 获取当前时间戳
|
||||
* @param timeOffset 允许时间回拨的毫秒数
|
||||
* @param randomSequenceLimit 限定一个随机上限,在不同毫秒下生成序号时,给定一个随机数,避免偶数问题,0表示无随机,上限不包括值本身。
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public Snowflake(final Date epochDate, final long workerId, final long dataCenterId,
|
||||
final boolean isUseSystemClock, final long timeOffset, final long randomSequenceLimit) {
|
||||
final boolean isUseSystemClock, final long randomSequenceLimit) {
|
||||
this.twepoch = (null != epochDate) ? epochDate.getTime() : DEFAULT_TWEPOCH;
|
||||
this.workerId = Assert.checkBetween(workerId, 0, MAX_WORKER_ID);
|
||||
this.dataCenterId = Assert.checkBetween(dataCenterId, 0, MAX_DATA_CENTER_ID);
|
||||
this.useSystemClock = isUseSystemClock;
|
||||
this.timeOffset = timeOffset;
|
||||
this.randomSequenceLimit = Assert.checkBetween(randomSequenceLimit, 0, SEQUENCE_MASK);
|
||||
}
|
||||
|
||||
@ -219,19 +196,16 @@ public class Snowflake implements Serializable {
|
||||
public synchronized long nextId() {
|
||||
long timestamp = genTime();
|
||||
if (timestamp < this.lastTimestamp) {
|
||||
if (this.lastTimestamp - timestamp < timeOffset) {
|
||||
// 容忍指定的回拨,避免NTP校时造成的异常
|
||||
timestamp = lastTimestamp;
|
||||
} else {
|
||||
// 如果服务器时间有问题(时钟后退) 报错。
|
||||
throw new IllegalStateException(StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", lastTimestamp - timestamp));
|
||||
}
|
||||
timestamp = lastTimestamp;
|
||||
}
|
||||
|
||||
if (timestamp == this.lastTimestamp) {
|
||||
// 时间出现回拨,递增序号
|
||||
final long sequence = (this.sequence + 1) & SEQUENCE_MASK;
|
||||
if (sequence == 0) {
|
||||
timestamp = tilNextMillis(lastTimestamp);
|
||||
// 如果序号耗尽,不再等待时间追赶,而是采用“超前消费”方式,让时间递增。
|
||||
// 这样可以避免系统暂停等待,而选择在“未来”ID新增不快时追上来。
|
||||
timestamp += 1;
|
||||
}
|
||||
this.sequence = sequence;
|
||||
} else {
|
||||
@ -295,27 +269,6 @@ public class Snowflake implements Serializable {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------ Private method start
|
||||
|
||||
/**
|
||||
* 循环等待下一个时间
|
||||
*
|
||||
* @param lastTimestamp 上次记录的时间
|
||||
* @return 下一个时间
|
||||
*/
|
||||
private long tilNextMillis(final long lastTimestamp) {
|
||||
long timestamp = genTime();
|
||||
// 循环直到操作系统时间戳变化
|
||||
while (timestamp == lastTimestamp) {
|
||||
timestamp = genTime();
|
||||
}
|
||||
if (timestamp < lastTimestamp) {
|
||||
// 如果发现新的时间戳比上次记录的时间戳数值小,说明操作系统时间发生了倒退,报错
|
||||
throw new IllegalStateException(
|
||||
StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", lastTimestamp - timestamp));
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成时间戳
|
||||
*
|
||||
|
@ -94,7 +94,7 @@ public class SnowflakeTest {
|
||||
@Disabled
|
||||
public void snowflakeRandomSequenceTest(){
|
||||
final Snowflake snowflake = new Snowflake(null, 0, 0,
|
||||
false, Snowflake.DEFAULT_TIME_OFFSET, 2);
|
||||
false, 2);
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
final long id = snowflake.nextId();
|
||||
Console.log(id);
|
||||
@ -107,7 +107,7 @@ public class SnowflakeTest {
|
||||
public void uniqueOfRandomSequenceTest(){
|
||||
// 测试并发环境下生成ID是否重复
|
||||
final Snowflake snowflake = new Snowflake(null, 0, 0,
|
||||
false, Snowflake.DEFAULT_TIME_OFFSET, 100);
|
||||
false, 100);
|
||||
|
||||
final Set<Long> ids = new ConcurrentHashSet<>();
|
||||
ThreadUtil.concurrencyTest(100, () -> {
|
||||
|
Loading…
Reference in New Issue
Block a user