优化代码

feature/net-util
ZhouXY108 2023-09-09 11:14:55 +08:00
parent 76b340e87d
commit e98a3e6fb6
1 changed files with 62 additions and 62 deletions

View File

@ -3,6 +3,7 @@ package xyz.zhouxy.plusone.commons.util;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
/** /**
* Twitter_Snowflake * Twitter_Snowflake
@ -11,20 +12,21 @@ import com.google.common.annotations.Beta;
public class SnowflakeIdGenerator { public class SnowflakeIdGenerator {
// ==============================Fields=========================================== // ==============================Fields===========================================
/** 开始时间截(北京时间 2008/08/08 20:00 */ /** 开始时间截(北京时间 2008/08/08 20:00 */
private static final long TWEPOCH = 1218196800000L; private static final long TWEPOCH = 1218196800000L;
/** 机器id所占的位数 */ /** 机器 id 所占的位数 */
private static final long WORKER_ID_BITS = 5L; private static final long WORKER_ID_BITS = 5L;
/** 数据标识id所占的位数 */ /** 数据标识 id 所占的位数 */
private static final long DATACENTER_ID_BITS = 5L; private static final long DATACENTER_ID_BITS = 5L;
/** 支持的最大机器 id结果是 31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */ /** 支持的最大机器 id结果是 31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
private static final long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS); private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
/** 支持的最大数据标识 id结果是 31 */ /** 支持的最大数据标识 id结果是 31 */
private static final long MAX_DATACENTER_ID = -1L ^ (-1L << DATACENTER_ID_BITS); private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS);
/** 序列在 id 中占的位数 */ /** 序列在 id 中占的位数 */
private static final long SEQUENCE_BITS = 12L; private static final long SEQUENCE_BITS = 12L;
@ -39,13 +41,10 @@ public class SnowflakeIdGenerator {
private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS; private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
/** 生成序列的掩码,这里为 4095 (0b111111111111=0xfff=4095) */ /** 生成序列的掩码,这里为 4095 (0b111111111111=0xfff=4095) */
private static final long SEQUENCE_MASK = -1L ^ (-1L << SEQUENCE_BITS); private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
/** 工作机器 ID (0~31) */ /** 数据中心 ID 和 工作机器 ID 偏移后的值 */
private final long workerId; private final long datacenterIdAndWorkerId;
/** 数据中心 ID (0~31) */
private final long datacenterId;
/** 毫秒内序列 (0~4095) */ /** 毫秒内序列 (0~4095) */
private long sequence = 0L; private long sequence = 0L;
@ -53,24 +52,24 @@ public class SnowflakeIdGenerator {
/** 上次生成 ID 的时间截 */ /** 上次生成 ID 的时间截 */
private long lastTimestamp = -1L; private long lastTimestamp = -1L;
/** 锁对象 */
private final Object lock = new Object();
// ==============================Constructors===================================== // ==============================Constructors=====================================
/** /**
* *
* *
* @param workerId ID (0~31) * @param workerId ID (0~31)
* @param datacenterId ID (0~31) * @param datacenterId ID (0~31)
*/ */
public SnowflakeIdGenerator(long workerId, long datacenterId) { public SnowflakeIdGenerator(final long workerId, final long datacenterId) {
if (workerId > MAX_WORKER_ID || workerId < 0) { Preconditions.checkArgument((workerId > MAX_WORKER_ID || workerId < 0),
throw new IllegalArgumentException( "WorkerId can't be greater than %s or less than 0.", MAX_WORKER_ID);
String.format("WorkerId can't be greater than %d or less than 0.", MAX_WORKER_ID)); Preconditions.checkArgument((datacenterId > MAX_DATACENTER_ID || datacenterId < 0),
} "DatacenterId can't be greater than %s or less than 0.", MAX_DATACENTER_ID);
if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) { this.datacenterIdAndWorkerId
throw new IllegalArgumentException( = (datacenterId << DATACENTER_ID_SHIFT) | (workerId << WORKER_ID_SHIFT);
String.format("DatacenterId can't be greater than %d or less than 0.", MAX_DATACENTER_ID));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
} }
// ==============================Methods========================================== // ==============================Methods==========================================
@ -79,52 +78,53 @@ public class SnowflakeIdGenerator {
* *
* @return SnowflakeId * @return SnowflakeId
*/ */
public synchronized long nextId() { public long nextId() {
long timestamp = timeGen(); long timestamp;
synchronized (lock) {
timestamp = timeGen();
// 发生了回拨,此刻时间小于上次发号时间 // 发生了回拨,此刻时间小于上次发号时间
if (timestamp < lastTimestamp) { if (timestamp < lastTimestamp) {
long offset = lastTimestamp - timestamp; long offset = lastTimestamp - timestamp;
if (offset <= 5) { if (offset <= 5) {
// 时间偏差大小小于5ms则等待两倍时间 // 时间偏差大小小于5ms则等待两倍时间
try { try {
TimeUnit.MILLISECONDS.sleep(offset << 1); TimeUnit.MILLISECONDS.sleep(offset << 1);
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
timestamp = timeGen(); timestamp = timeGen();
if (timestamp < lastTimestamp) { if (timestamp < lastTimestamp) {
// 还是小于,抛异常上报 // 还是小于,抛异常上报
throwClockBackwardsEx(lastTimestamp, timestamp);
}
} else {
throwClockBackwardsEx(lastTimestamp, timestamp); throwClockBackwardsEx(lastTimestamp, timestamp);
} }
} else {
throwClockBackwardsEx(lastTimestamp, timestamp);
} }
}
// 如果是同一时间生成的,则进行毫秒内序列 // 如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) { if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & SEQUENCE_MASK; sequence = (sequence + 1) & SEQUENCE_MASK;
// 毫秒内序列溢出 // 毫秒内序列溢出
if (sequence == 0) { if (sequence == 0) {
// 阻塞到下一个毫秒,获得新的时间戳 // 阻塞到下一个毫秒,获得新的时间戳
timestamp = tilNextMillis(lastTimestamp); timestamp = tilNextMillis(lastTimestamp);
}
}
// 时间戳改变,毫秒内序列重置
else {
sequence = 0L;
} }
}
// 时间戳改变,毫秒内序列重置
else {
sequence = 0L;
}
// 上次生成 ID 的时间截 // 上次生成 ID 的时间截
lastTimestamp = timestamp; lastTimestamp = timestamp;
}
// 移位并通过或运算拼到一起组成64位的ID // 移位并通过或运算拼到一起组成64位的ID
return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) // return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) | datacenterIdAndWorkerId | sequence;
| (datacenterId << DATACENTER_ID_SHIFT) //
| (workerId << WORKER_ID_SHIFT) //
| sequence;
} }
/** /**