/** * ID生成器,基于Snowflake算法实现。 * 用于生成全局唯一且递增的ID。 */ public class IdGenerator {
// 起始时间戳,用于计算相对于此时间的毫秒数 public static final long START_STAMP = DateUtil.get("2022-1-1").getTime();
// 定义数据中心位数、机器位数和序列号位数 public static final long DATA_CENTER_BIT = 5L; public static final long MACHINE_BIT = 5L; public static final long SEQUENCE_BIT = 12L;
// 根据位数计算最大值 public static final long DATA_CENTER_MAX = ~(-1L << DATA_CENTER_BIT); public static final long MACHINE_MAX = ~(-1L << MACHINE_BIT); public static final long SEQUENCE_MAX = ~(-1L << SEQUENCE_BIT);
// 定义时间戳、数据中心、机器号和序列号的位移 public static final long TIMESTAMP_LEFT = DATA_CENTER_BIT + MACHINE_BIT + SEQUENCE_BIT; public static final long DATA_CENTER_LEFT = MACHINE_BIT + SEQUENCE_BIT; public static final long MACHINE_LEFT = SEQUENCE_BIT;
// 数据中心ID、机器ID和序列号 private long dataCenterId; private long machineId; private LongAdder sequenceId = new LongAdder(); // 记录上一次的时间戳,用于处理时钟回拨问题 private long lastTimeStamp = -1L;
/** * 获取下一个时间戳,用于处理时钟回拨情况。 * @return 下一个时间戳 */ private long getNextTimeStamp() { long current = System.currentTimeMillis() - START_STAMP; // 如果当前时间与上一次时间相同,则循环等待直到时间戳改变 while (current == lastTimeStamp){ current = System.currentTimeMillis() - START_STAMP; } return current; }
public static void main(String[] args) { IdGenerator idGenerator = new IdGenerator(1,2); for (int i = 0; i < 1000; i++) { new Thread(() -> System.out.println(idGenerator.getId())).start(); } } }