|
@@ -1,127 +0,0 @@
|
|
-package com.galaxis.manatee.util.impl;
|
|
|
|
-
|
|
|
|
-import com.galaxis.manatee.util.IdGenerate;
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * 雪花算法生成Id
|
|
|
|
- * @author zcj
|
|
|
|
- * @version 0.1
|
|
|
|
- * @date 2020/1/8 11:40 下午
|
|
|
|
- */
|
|
|
|
-public class SnowflakeIdGenerator implements IdGenerate<Long> {
|
|
|
|
- private static SnowflakeIdGenerator snowflakeIdWorker;
|
|
|
|
-
|
|
|
|
- private static final Object LOOK = new Object();
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 获取 snowflake
|
|
|
|
- * @param dataCenterId 数据中心ID (0~31)
|
|
|
|
- */
|
|
|
|
- public static SnowflakeIdGenerator getSnowflakeIdGenerator(long dataCenterId){
|
|
|
|
- if(null == snowflakeIdWorker){
|
|
|
|
- snowflakeIdWorker=new SnowflakeIdGenerator(dataCenterId);
|
|
|
|
- }
|
|
|
|
- return snowflakeIdWorker;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // ==============================Fields===========================================
|
|
|
|
-
|
|
|
|
- /** 数据标识id所占的位数 */
|
|
|
|
- private final long dataCenterIdBits = 10L;
|
|
|
|
-
|
|
|
|
- /** 数据中心ID(0~31) */
|
|
|
|
- private long dataCenterId;
|
|
|
|
-
|
|
|
|
- /** 毫秒内序列(0~4095) */
|
|
|
|
- private long sequence = 0L;
|
|
|
|
-
|
|
|
|
- /** 上次生成ID的时间截 */
|
|
|
|
- private long lastTimestamp = -1L;
|
|
|
|
-
|
|
|
|
- //==============================Constructors=====================================
|
|
|
|
- /**
|
|
|
|
- * 构造函数
|
|
|
|
- * @param dataCenterId 数据中心ID (0~31)
|
|
|
|
- */
|
|
|
|
- private SnowflakeIdGenerator(long dataCenterId) {
|
|
|
|
- // 支持的最大数据标识id,结果是31
|
|
|
|
- long maxDataCenterId = ~(-1L << dataCenterIdBits);
|
|
|
|
- if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
|
|
|
|
- throw new IllegalArgumentException(String.format("dataCenter Id can't be greater than %d or less than 0", maxDataCenterId));
|
|
|
|
- }
|
|
|
|
- this.dataCenterId = dataCenterId;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // ==============================Methods==========================================
|
|
|
|
- /**
|
|
|
|
- * 获得下一个ID (该方法是线程安全的)
|
|
|
|
- * @return SnowflakeId
|
|
|
|
- */
|
|
|
|
- @Override
|
|
|
|
- public synchronized Long nextId() {
|
|
|
|
-
|
|
|
|
- synchronized (LOOK){
|
|
|
|
- long timeStamp = timeGen();
|
|
|
|
-
|
|
|
|
- //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
|
|
|
|
- if (timeStamp < lastTimestamp) {
|
|
|
|
- throw new RuntimeException(
|
|
|
|
- String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timeStamp));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //如果是同一时间生成的,则进行毫秒内序列
|
|
|
|
- // 序列在id中占的位数 */
|
|
|
|
- long sequenceBits = 12L;
|
|
|
|
- if (lastTimestamp == timeStamp) {
|
|
|
|
- // 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
|
|
|
|
- long sequenceMask = ~(-1L << sequenceBits);
|
|
|
|
- sequence = (sequence + 1) & sequenceMask;
|
|
|
|
- //毫秒内序列溢出
|
|
|
|
- if (sequence == 0) {
|
|
|
|
- //阻塞到下一个毫秒,获得新的时间戳
|
|
|
|
- timeStamp = tilNextMillis(lastTimestamp);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- //时间戳改变,毫秒内序列重置
|
|
|
|
- else {
|
|
|
|
- sequence = 0L;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //上次生成ID的时间截
|
|
|
|
- lastTimestamp = timeStamp;
|
|
|
|
-
|
|
|
|
- //移位并通过或运算拼到一起组成64位的ID
|
|
|
|
- // 开始时间截 (2015-01-01)
|
|
|
|
- long startTimeStamp = 1420041600000L;
|
|
|
|
- // 时间截向左移22位(5+5+12) */
|
|
|
|
- long timestampLeftShift = sequenceBits + dataCenterIdBits;
|
|
|
|
- // 数据标识id向左移17位(12+5) */
|
|
|
|
- return ((timeStamp - startTimeStamp) << timestampLeftShift)
|
|
|
|
- | (dataCenterId << sequenceBits)
|
|
|
|
- | sequence;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 阻塞到下一个毫秒,直到获得新的时间戳
|
|
|
|
- * @param lastTimestamp 上次生成ID的时间截
|
|
|
|
- * @return 当前时间戳
|
|
|
|
- */
|
|
|
|
- private long tilNextMillis(long lastTimestamp) {
|
|
|
|
- long timestamp = timeGen();
|
|
|
|
- while (timestamp <= lastTimestamp) {
|
|
|
|
- timestamp = timeGen();
|
|
|
|
- }
|
|
|
|
- return timestamp;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 返回以毫秒为单位的当前时间
|
|
|
|
- * @return 当前时间(毫秒)
|
|
|
|
- */
|
|
|
|
- private long timeGen() {
|
|
|
|
- return System.currentTimeMillis();
|
|
|
|
- }
|
|
|
|
-}
|
|
|