123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package com.zhentao.utils;
- import java.time.LocalDateTime;
- import java.time.ZoneOffset;
- public class SnowflakeIdGenerator {
- // 基础配置(Java 8+)
- private static final long EPOCH = 1288834974657L; // 2010-11-04 00:00:00 UTC
- private static final int DATACENTER_ID_BITS = 5;
- private static final int WORKER_ID_BITS = 5;
- private static final int SEQUENCE_BITS = 12;
- // 位运算掩码
- private static final long DATACENTER_ID_MASK = (1L << DATACENTER_ID_BITS) - 1;
- private static final long WORKER_ID_MASK = (1L << WORKER_ID_BITS) - 1;
- private static final long SEQUENCE_MASK = (1L << SEQUENCE_BITS) - 1;
- // 位移偏移量
- private static final int WORKER_ID_SHIFT = SEQUENCE_BITS;
- private static final int DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
- private static final int TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
- private final long datacenterId;
- private final long workerId;
- private long sequence = 0L;
- private long lastTimestamp = -1L;
- private final Object lock = new Object();
- public SnowflakeIdGenerator(long datacenterId, long workerId) {
- if ((datacenterId & DATACENTER_ID_MASK) != datacenterId) {
- throw new IllegalArgumentException("DataCenter ID 必须在 0-31 之间");
- }
- if ((workerId & WORKER_ID_MASK) != workerId) {
- throw new IllegalArgumentException("Worker ID 必须在 0-31 之间");
- }
- this.datacenterId = datacenterId;
- this.workerId = workerId;
- }
- public synchronized long nextId() {
- long currentTimestamp = timeGen();
- if (currentTimestamp < lastTimestamp) {
- throw new IllegalStateException(
- String.format("时钟回退 %d 毫秒,禁止生成ID(上次: %d,当前: %d)",
- lastTimestamp - currentTimestamp, lastTimestamp, currentTimestamp));
- }
- if (currentTimestamp == lastTimestamp) {
- sequence = (sequence + 1) & SEQUENCE_MASK;
- if (sequence == 0) {
- currentTimestamp = waitNextMillis(lastTimestamp);
- }
- } else {
- sequence = 0;
- }
- lastTimestamp = currentTimestamp;
- return ((currentTimestamp - EPOCH) << TIMESTAMP_SHIFT) |
- (datacenterId << DATACENTER_ID_SHIFT) |
- (workerId << WORKER_ID_SHIFT) |
- sequence;
- }
- private long waitNextMillis(long lastTimestamp) {
- long timestamp = timeGen();
- while (timestamp <= lastTimestamp) {
- timestamp = System.currentTimeMillis(); // 改用更可靠的时间源
- }
- return timestamp;
- }
- private long timeGen() {
- return System.currentTimeMillis();
- }
- // 添加 parseId 方法
- public static SnowflakeMeta parseId(long snowflakeId) {
- long sequence = snowflakeId & SEQUENCE_MASK;
- long workerId = (snowflakeId >> WORKER_ID_SHIFT) & WORKER_ID_MASK;
- long datacenterId = (snowflakeId >> DATACENTER_ID_SHIFT) & DATACENTER_ID_MASK;
- long timestamp = (snowflakeId >> TIMESTAMP_SHIFT) + EPOCH;
- return new SnowflakeMeta(
- timestamp,
- datacenterId,
- workerId,
- sequence,
- LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.ofHours(8))
- );
- }
- public static Long getSnowId(){
- SnowflakeIdGenerator generator=new SnowflakeIdGenerator(1,1);
- Long id=generator.nextId();
- SnowflakeMeta meta=SnowflakeIdGenerator.parseId(id);
- return id;
- }
- // ---------------- 修复:添加完整的getter方法 ----------------
- public static class SnowflakeMeta {
- private final long timestamp;
- private final long datacenterId;
- private final long workerId;
- private final long sequence;
- private final LocalDateTime dateTime;
- public SnowflakeMeta(long timestamp, long datacenterId, long workerId, long sequence, LocalDateTime dateTime) {
- this.timestamp = timestamp;
- this.datacenterId = datacenterId;
- this.workerId = workerId;
- this.sequence = sequence;
- this.dateTime = dateTime;
- }
- // 显式定义getter(修复爆红)
- public long getTimestamp() {
- return timestamp;
- }
- public long getDatacenterId() {
- return datacenterId;
- }
- public long getWorkerId() {
- return workerId;
- }
- public long getSequence() {
- return sequence;
- }
- public LocalDateTime getDateTime() {
- return dateTime;
- }
- }
- }
|