本文目录导读:

我来为你详细介绍Java中雪花算法的实现案例。
基础雪花算法实现
public class SnowflakeIdWorker {
// ============================== 核心参数 ==============================
/** 开始时间戳 (2020-01-01) */
private final long epoch = 1577836800000L;
/** 机器ID所占位数 */
private final long workerIdBits = 5L;
/** 数据中心ID所占位数 */
private final long dataCenterIdBits = 5L;
/** 序列号所占位数 */
private final long sequenceBits = 12L;
/** 机器ID最大值 (31) */
private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
/** 数据中心ID最大值 (31) */
private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits);
/** 机器ID左移位数 (12) */
private final long workerIdShift = sequenceBits;
/** 数据中心ID左移位数 (12+5=17) */
private final long dataCenterIdShift = sequenceBits + workerIdBits;
/** 时间戳左移位数 (12+5+5=22) */
private final long timestampShift = sequenceBits + workerIdBits + dataCenterIdBits;
/** 序列号掩码 (4095) */
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
// ============================== 实例变量 ==============================
private long workerId;
private long dataCenterId;
private long sequence = 0L;
private long lastTimestamp = -1L;
// ============================== 构造方法 ==============================
public SnowflakeIdWorker(long workerId, long dataCenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(
String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
throw new IllegalArgumentException(
String.format("datacenter Id can't be greater than %d or less than 0", maxDataCenterId));
}
this.workerId = workerId;
this.dataCenterId = dataCenterId;
}
// ============================== 核心方法 ==============================
public synchronized long nextId() {
long timestamp = timeGen();
// 时间回拨处理
if (timestamp < lastTimestamp) {
throw new RuntimeException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
lastTimestamp - timestamp));
}
// 同一毫秒内
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
// 序列号用完,等待下一毫秒
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
// 不同毫秒,重置序列号
sequence = 0L;
}
lastTimestamp = timestamp;
// 生成最终ID
return ((timestamp - epoch) << timestampShift) |
(dataCenterId << dataCenterIdShift) |
(workerId << workerIdShift) |
sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
}
高级版本(包含回拨处理)
public class AdvancedSnowflakeIdWorker {
// ============================== 配置参数 ==============================
private static final long SEQUENCE_BITS = 12L;
private static final long WORKER_ID_BITS = 5L;
private static final long DATA_CENTER_ID_BITS = 5L;
private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
private static final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);
private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
private static final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS;
// ============================== 时间回拨容忍度(毫秒) ==============================
private static final long BACKWARD_TOLERANCE = 1000L;
private long dataCenterId;
private long workerId;
private volatile long sequence = 0L;
private volatile long lastTimestamp = -1L;
private final AtomicBoolean lock = new AtomicBoolean(false);
// ============================== 构造方法 ==============================
public AdvancedSnowflakeIdWorker(long dataCenterId, long workerId) {
if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {
throw new IllegalArgumentException("数据中心ID超出范围");
}
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException("工作机器ID超出范围");
}
this.dataCenterId = dataCenterId;
this.workerId = workerId;
}
// ============================== 核心方法 ==============================
public long nextId() {
long timestamp = currentTimeMillis();
// 时间回拨处理
if (timestamp < lastTimestamp) {
long offset = lastTimestamp - timestamp;
if (offset <= BACKWARD_TOLERANCE) {
// 小幅度回拨,等待时间追上
timestamp = waitForTime(lastTimestamp);
} else {
// 大幅度回拨,抛异常
throw new RuntimeException("系统时间回拨超过容忍度");
}
}
// CAS方式保证线程安全
while (true) {
if (lock.compareAndSet(false, true)) {
try {
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & SEQUENCE_MASK;
if (sequence == 0) {
timestamp = waitForNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
} finally {
lock.set(false);
}
break;
}
}
return generateId(timestamp);
}
private long generateId(long timestamp) {
return ((timestamp - getEpoch()) << TIMESTAMP_SHIFT) |
(dataCenterId << DATA_CENTER_ID_SHIFT) |
(workerId << WORKER_ID_SHIFT) |
sequence;
}
private long waitForTime(long lastTimestamp) {
long timestamp = currentTimeMillis();
while (timestamp < lastTimestamp) {
timestamp = currentTimeMillis();
}
return timestamp;
}
private long waitForNextMillis(long lastTimestamp) {
long timestamp = currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = currentTimeMillis();
}
return timestamp;
}
private long getEpoch() {
return 1577836800000L; // 2020-01-01 00:00:00
}
private long currentTimeMillis() {
return System.currentTimeMillis();
}
}
使用示例
public class SnowflakeDemo {
public static void main(String[] args) {
// 创建ID生成器
SnowflakeIdWorker idWorker = new SnowflakeIdWorker(1, 1);
AdvancedSnowflakeIdWorker advancedWorker = new AdvancedSnowflakeIdWorker(1, 1);
// 测试基础版本
System.out.println("===== 基础版本测试 =====");
for (int i = 0; i < 10; i++) {
long id = idWorker.nextId();
System.out.println("ID: " + id + " (长度: " + String.valueOf(id).length() + ")");
}
// 测试高级版本
System.out.println("\n===== 高级版本测试 =====");
for (int i = 0; i < 10; i++) {
long id = advancedWorker.nextId();
System.out.println("ID: " + id + " (长度: " + String.valueOf(id).length() + ")");
}
// 多线程测试
System.out.println("\n===== 多线程测试 =====");
testMultiThread(idWorker, 100);
}
private static void testMultiThread(SnowflakeIdWorker idWorker, int count) {
Set<Long> ids = new ConcurrentSkipListSet<>();
CountDownLatch latch = new CountDownLatch(count);
for (int i = 0; i < count; i++) {
new Thread(() -> {
try {
long id = idWorker.nextId();
ids.add(id);
} finally {
latch.countDown();
}
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("生成ID数量: " + ids.size());
System.out.println("是否全部唯一: " + (ids.size() == count));
}
}
Spring Boot集成示例
@Component
public class SnowflakeIdGenerator {
@Value("${snowflake.worker-id:1}")
private long workerId;
@Value("${snowflake.datacenter-id:1}")
private long dataCenterId;
private SnowflakeIdWorker snowflakeIdWorker;
@PostConstruct
public void init() {
this.snowflakeIdWorker = new SnowflakeIdWorker(workerId, dataCenterId);
}
public long nextId() {
return snowflakeIdWorker.nextId();
}
public String nextIdStr() {
return String.valueOf(snowflakeIdWorker.nextId());
}
}
// 使用方式
@Service
public class UserService {
@Autowired
private SnowflakeIdGenerator idGenerator;
public User createUser(String name) {
User user = new User();
user.setId(idGenerator.nextId());
user.setName(name);
// ... 保存用户
return user;
}
}
自定义位数版本
public class CustomSnowflakeIdWorker {
private final long workerId;
private final long sequenceBits;
private final long sequenceMask;
private volatile long lastTimestamp = -1L;
private volatile long sequence = 0L;
public CustomSnowflakeIdWorker(long workerId, long sequenceBits) {
this.workerId = workerId;
this.sequenceBits = sequenceBits;
this.sequenceMask = -1L ^ (-1L << sequenceBits);
}
public synchronized long nextId() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) {
throw new RuntimeException("时钟回拨");
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
return (timestamp << (63 - sequenceBits)) | (workerId << sequenceBits) | sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
}
注意事项
- 唯一性保证:确保不同服务的
workerId和dataCenterId不重复 - 序列号溢出:单毫秒内生成的ID超过4095时,等待下一毫秒
- 时钟回拨:需要处理系统时间回拨的情况
- 线程安全:使用
synchronized或CAS保证线程安全 - 性能优化:预计算移位参数,减少运行时计算
这个实现已经在很多分布式系统中得到验证,性能优异,单机每秒可生成数百万个ID。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播