SnowflakeUtil.java 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package com.zhentao.utils;
  2. /**
  3. * @Date 2025/4/21 19:25
  4. * @Author gln
  5. **/
  6. public class SnowflakeUtil {
  7. // 起始时间戳,可自定义,这里以 2020-01-01 00:00:00 为例
  8. private static final long START_TIMESTAMP = 1577836800000L;
  9. // 数据中心 ID 所占位数
  10. private static final long DATA_CENTER_ID_BITS = 5L;
  11. // 机器 ID 所占位数
  12. private static final long WORKER_ID_BITS = 5L;
  13. // 序列号所占位数
  14. private static final long SEQUENCE_BITS = 12L;
  15. // 数据中心 ID 最大值
  16. private static final long MAX_DATA_CENTER_ID = -1L ^ (-1L << DATA_CENTER_ID_BITS);
  17. // 机器 ID 最大值
  18. private static final long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS);
  19. // 序列号最大值
  20. private static final long SEQUENCE_MASK = -1L ^ (-1L << SEQUENCE_BITS);
  21. // 机器 ID 向左移位数
  22. private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
  23. // 数据中心 ID 向左移位数
  24. private static final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
  25. // 时间戳向左移位数
  26. private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS;
  27. // 固定数据中心 ID 和机器 ID
  28. private static final long DATA_CENTER_ID = 1;
  29. private static final long WORKER_ID = 1;
  30. private static long sequence = 0L;
  31. private static long lastTimestamp = -1L;
  32. public static synchronized long nextId() {
  33. long timestamp = System.currentTimeMillis();
  34. if (timestamp < lastTimestamp) {
  35. throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds");
  36. }
  37. if (timestamp == lastTimestamp) {
  38. sequence = (sequence + 1) & SEQUENCE_MASK;
  39. if (sequence == 0) {
  40. timestamp = waitForNextMillis(lastTimestamp);
  41. }
  42. } else {
  43. sequence = 0L;
  44. }
  45. lastTimestamp = timestamp;
  46. return ((timestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_SHIFT) |
  47. (DATA_CENTER_ID << DATA_CENTER_ID_SHIFT) |
  48. (WORKER_ID << WORKER_ID_SHIFT) |
  49. sequence;
  50. }
  51. private static long waitForNextMillis(long lastTimestamp) {
  52. long timestamp = System.currentTimeMillis();
  53. while (timestamp <= lastTimestamp) {
  54. timestamp = System.currentTimeMillis();
  55. }
  56. return timestamp;
  57. }
  58. public static void main(String[] args) {
  59. for (int i = 0; i < 10; i++) {
  60. System.out.println(nextId());
  61. }
  62. }
  63. }