SnowFlake.java 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package com.zd.model.domain.tool;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. /**
  5. * <p>雪花算法获取编号</p>
  6. *
  7. * @author lft
  8. * @date 2019/1/18
  9. * @since jdk1.8
  10. * @version 1.0
  11. */
  12. public class SnowFlake {
  13. private static Logger LOGGER = LoggerFactory.getLogger(SnowFlake.class);
  14. /**
  15. * 起始的时间戳
  16. */
  17. private final static long START_STAMP = 1530374400000L;
  18. /**
  19. * 序列号占用的位数
  20. */
  21. private final static long SEQUENCE_BIT = 12;
  22. /**
  23. * 机器标识占用的位数
  24. */
  25. private final static long MACHINE_BIT = 5;
  26. /**
  27. * 数据中心占用的位数
  28. */
  29. private final static long DATACENTER_BIT = 5;
  30. /**
  31. * 数据中心ID最大值
  32. */
  33. private final static long MAX_DATACENTER_NUM = ~(-1L << DATACENTER_BIT);
  34. /**
  35. * 机器ID最大值
  36. */
  37. private final static long MAX_MACHINE_NUM = ~(-1L << MACHINE_BIT);
  38. /**
  39. * 序列号最大值
  40. */
  41. private final static long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);
  42. private final static long MACHINE_LEFT = SEQUENCE_BIT;
  43. private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
  44. private final static long TIMESTAMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
  45. /**
  46. * 数据中心ID
  47. */
  48. private final long datacenterId;
  49. /**
  50. * 机器ID
  51. */
  52. private final long machineId;
  53. /**
  54. * 序列号ID
  55. */
  56. private long sequence = 0L;
  57. /**
  58. * 上一次时间戳
  59. */
  60. private long lastStamp = -1L;
  61. /**
  62. * 构造方法,初始化数据中心ID和机器ID
  63. * @param datacenterId 数据中心ID
  64. * @param machineId 机器ID
  65. */
  66. public SnowFlake(long datacenterId, long machineId) {
  67. if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0)
  68. throw new IllegalArgumentException("DatacenterId can't be greater than " + MAX_DATACENTER_NUM + " or less than 0 !");
  69. if (machineId > MAX_MACHINE_NUM || machineId < 0)
  70. throw new IllegalArgumentException("MachineId can't be greater than " + MAX_MACHINE_NUM + " or less than 0 !");
  71. this.datacenterId = datacenterId;
  72. this.machineId = machineId;
  73. }
  74. /**
  75. * 使用雪花算法生成ID
  76. * @return ID
  77. */
  78. public synchronized long nextId() {
  79. long currStamp = System.currentTimeMillis();
  80. if (currStamp < lastStamp)
  81. throw new RuntimeException("The system clock rolls back, refuses to generate ID !");
  82. if (currStamp == lastStamp) {
  83. // 相同毫秒内,序列号自增
  84. sequence = (sequence + 1) & MAX_SEQUENCE;
  85. // 同一毫秒的序列数已经达到最大
  86. if (sequence == 0L) {
  87. while (currStamp <= lastStamp) currStamp = System.currentTimeMillis();
  88. }
  89. } else {
  90. // 不同毫秒内,序列号置为0
  91. sequence = 0L;
  92. }
  93. lastStamp = currStamp;
  94. return (currStamp - START_STAMP) << TIMESTAMP_LEFT | datacenterId << DATACENTER_LEFT | machineId << MACHINE_LEFT | sequence;
  95. }
  96. public static void main(String[] args) {
  97. SnowFlake snowFlake = new SnowFlake(1, 1);
  98. }
  99. }