package com.ruoyi.project.common; import java.net.InetAddress; import java.util.concurrent.ThreadLocalRandom; public class IdGeneratorUtils { // 机器ID(0-31) private static final long MACHINE_ID = getMachineId() & 31L; // 时间戳左移的位数(22位给计数器,5位给机器ID) private static final long TIMESTAMP_SHIFT = 22 + 5; private static final long COUNTER_BITS = 22L; private static final long MAX_COUNTER = (1L << COUNTER_BITS) - 1; private static long lastTimestamp = -1L; private static long counter = 0L; public synchronized static long nextId() { long timestamp = System.currentTimeMillis(); if (timestamp < lastTimestamp) { throw new RuntimeException("Clock moved backwards"); } if (timestamp == lastTimestamp) { counter = (counter + 1) & MAX_COUNTER; if (counter == 0) { // 同一毫秒内计数器用完,等待下一毫秒 timestamp = waitNextMillis(lastTimestamp); } } else { counter = 0L; } lastTimestamp = timestamp; return ((timestamp) << TIMESTAMP_SHIFT) | (MACHINE_ID << COUNTER_BITS) | counter; } private static long waitNextMillis(long lastTimestamp) { long timestamp = System.currentTimeMillis(); while (timestamp <= lastTimestamp) { timestamp = System.currentTimeMillis(); } return timestamp; } private static long getMachineId() { try { // 可以根据需要获取机器标识,比如IP地址最后一段 String hostAddress = InetAddress.getLocalHost().getHostAddress(); return Long.parseLong(hostAddress.split("\\.")[3]); } catch (Exception e) { return ThreadLocalRandom.current().nextLong(32); } } }