package com.ycwl.basic.utils; import com.ycwl.basic.model.snowFlake.UniqueId; import com.ycwl.basic.model.snowFlake.UniqueIdMetaData; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Date; /** * @author Created by liuhongguang * @Description */ @Slf4j @Component public class SnowFlakeUtil { /** * 记录上一毫秒数 */ private static long lastTimestamp = -1L; /** * 记录毫秒内的序列,0-4095 */ private static long sequence = 0L; private static Long machineId = 1L; private static Long datacenterId =1L; public static synchronized String getId() { long timestamp = System.currentTimeMillis(); // 如果当前时间小于上一次ID生成的时间戳,说明系统时钟被修改过,回退在上一次ID生成时间之前应当抛出异常!!! if (timestamp < lastTimestamp) { throw new IllegalStateException( String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } //如果是同一时间生成的,则进行毫秒内序列 if (lastTimestamp == timestamp) { sequence = (sequence + 1) & UniqueIdMetaData.SEQUENCE_MASK; //毫秒内序列溢出 if (sequence == 0) { //阻塞到下一个毫秒,获得新的时间戳 timestamp = System.currentTimeMillis(); while (timestamp <= lastTimestamp) { timestamp = System.currentTimeMillis(); } return String.valueOf(timestamp); } } //时间戳改变,毫秒内序列重置 else { sequence = 0L; } // 上次生成ID的时间截 lastTimestamp = timestamp; // 移位并通过或运算组成64位ID return String.valueOf(((timestamp - UniqueIdMetaData.START_TIME) << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS) | (datacenterId << UniqueIdMetaData.DATACENTER_SHIFT_BITS) | (machineId<< UniqueIdMetaData.MACHINE_SHIFT_BITS) | sequence); } public static Long getLongId(){ return Long.valueOf(getId()); } public UniqueId explainId(long id) { UniqueId uniqueId = com.ycwl.basic.utils.SnowFlakeUtil.convert(id); if (uniqueId == null) { log.error("==> 解析ID失败, ID不合法"); return null; } return uniqueId; } public Date transTime(long time) { return new Date(time + UniqueIdMetaData.START_TIME); } /** * 唯一ID对象解析返回ID * * @param uniqueId * @return */ public static long convert(UniqueId uniqueId) { long result = 0; try { result |= uniqueId.getSequence(); result |= uniqueId.getMachineId() << UniqueIdMetaData.MACHINE_SHIFT_BITS; result |= uniqueId.getDatacenterId() << UniqueIdMetaData.DATACENTER_SHIFT_BITS; result |= uniqueId.getTimestamp() << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS; } catch (Exception e) { e.printStackTrace(); return result; } return result; } public static UniqueId convert(long id) { UniqueId uniqueId = null; try { uniqueId = new UniqueId(); uniqueId.setSequence(id & UniqueIdMetaData.SEQUENCE_MASK); uniqueId.setMachineId((id >>> UniqueIdMetaData.MACHINE_SHIFT_BITS) & UniqueIdMetaData.MACHINE_MASK); uniqueId.setDatacenterId((id >>> UniqueIdMetaData.DATACENTER_SHIFT_BITS) & UniqueIdMetaData.DATACENTER_MASK); uniqueId.setTimestamp((id >>> UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS) & UniqueIdMetaData.TIMESTAMP_MASK); } catch (Exception e) { e.printStackTrace(); return uniqueId; } return uniqueId; } }