Java最新今日话题:分布式 ID 生成器 ~ ~,不可多得的干货
在分布式系统中,需要生成唯一的ID,用以标识用户、订单、消息等。常见的方法有UUID、数据库自增ID、雪花算法(Snowflake)等。以下是一个使用雪花算法(Snowflake)生成分布式ID的Java示例代码:
import java.util.concurrent.atomic.AtomicLong;
public class SnowflakeIdGenerator {
// 起始时间戳 (2023-01-01)
private static final long EPOCH = 1670000000000L;
// 机器ID所占的位数
private static final long MACHINE_ID_BITS = 5L;
// 数据中心ID所占的位数
private static final long DATACENTER_ID_BITS = 5L;
// 序列号所占的位数
private static final long SEQUENCE_BITS = 12L;
// 机器ID向左移动的位数
private static final long MACHINE_ID_SHIFT = SEQUENCE_BITS;
// 数据中心ID向左移动的位数
private static final long DATACENTER_ID_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS;
// 时间戳向左移动的位数
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS + DATACENTER_ID_BITS;
// 最大机器ID值
private static final long MAX_MACHINE_ID = ~(-1L << MACHINE_ID_BITS);
// 最大数据中心ID值
private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS);
// 最大序列号值
private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);
// 机器ID
private static long machineId;
// 数据中心ID
private static long datacenterId;
// 序列号
private static AtomicLong sequence = new AtomicLong(0);
// 上次生成ID的时间戳
private static long lastTimestamp = -1L;
public static synchronized long nextId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException("时钟回退,总线度ID生成失败!");
}
if (currentTimestamp == lastTimestamp) {
long currentSequence = sequence.getAndIncrement() & MAX_SEQUENCE;
if (currentSequence >= MAX_SEQUENCE) {
currentTimestamp = tillNextMillis(lastTimestamp);
}
} else {
sequence.set(0);
}
lastTimestamp = currentTimestamp;
long id = ((currentTimestamp - EPOCH) << TIMESTAMP_SHIFT)
| (machineId << MACHINE_ID_SHIFT)
| (datacenterId << DATACENTER_ID_SHIFT)
| sequence.get();
return id;
}
private static long tillNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <
评论已关闭