package com.kwan.springbootkwan.utils; public class SnowflakeUtil { private static final long EPOCH = 1630444800000L; // 设置一个起始时间戳,例如:2021-09-01 00:00:00 private static final long MACHINE_ID_BITS = 5; private static final long DATACENTER_ID_BITS = 5; private static final long SEQUENCE_BITS = 12; private static final long MAX_MACHINE_ID = (1L << MACHINE_ID_BITS) - 1; private static final long MAX_DATACENTER_ID = (1L << DATACENTER_ID_BITS) - 1; private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1; private final long machineId; private final long datacenterId; private long lastTimestamp = -1L; private long sequence = 0L; public SnowflakeUtil(long machineId, long datacenterId) { if (machineId > MAX_MACHINE_ID || machineId < 0) { throw new IllegalArgumentException("Invalid machine ID"); } if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) { throw new IllegalArgumentException("Invalid datacenter ID"); } this.machineId = machineId; this.datacenterId = datacenterId; } public synchronized long nextId() { long timestamp = System.currentTimeMillis(); if (timestamp < lastTimestamp) { throw new RuntimeException("Clock moved backwards. Refusing to generate ID."); } if (timestamp == lastTimestamp) { sequence = (sequence + 1) & MAX_SEQUENCE; if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0; } lastTimestamp = timestamp; return ((timestamp - EPOCH) << (MACHINE_ID_BITS + DATACENTER_ID_BITS + SEQUENCE_BITS)) | (datacenterId << (MACHINE_ID_BITS + SEQUENCE_BITS)) | (machineId << SEQUENCE_BITS) | sequence; } private long tilNextMillis(long lastTimestamp) { long timestamp = System.currentTimeMillis(); while (timestamp <= lastTimestamp) { timestamp = System.currentTimeMillis(); } return timestamp; } }