Twitter-Snowflake生成
snowflake,64位自增ID算法:
第一位为0(不用),41位时间戳,10位工作机器id,12位序列号组合在一起
时间戳生成:
uint64_t generateStamp()
{
timeval tv;
gettimeofday(&tv, 0);
return (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000;
}
序列号生成:
uint64_t waitNextMs( uint64_t lastStamp){uint64_t cur = 0; do {cur = generateStamp(); } while (cur <= lastStamp); return cur; } 算法实现:
【Twitter-Snowflake生成】
public class IdWorker { private final long twepoch = 1288834974657L; // 机器标识位数 private final long workerIdBits = 5L; // 数据中心标识位数 private final long datacenterIdBits = 5L; // 机器ID最大值 31 private final long maxWorkerId = -1L ^ (-1L << workerIdBits); // 数据中心ID最大值 31 private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 毫秒内自增位 private final long sequenceBits = 12L; // 机器ID偏左移12位 private final long workerIdShift = sequenceBits; private final long datacenterIdShift = sequenceBits + workerIdBits; // 时间毫秒左移22位 private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; private final long sequenceMask = -1L ^ (-1L << sequenceBits); private long workerId; private long datacenterId; private long sequence = 0L; private long lastTimestamp = -1L; public IdWorker(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; }public synchronized long nextId() { long timestamp = timeGen(); if (timestamp < lastTimestamp) { throw new RuntimeException(String.format("Clock moved backwards.Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } if (lastTimestamp == timestamp) { // 当前毫秒内,则+1 sequence = (sequence + 1) & sequenceMask; // 当前毫秒内计数满了,则等待下一秒 if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0L; }lastTimestamp = timestamp; // ID偏移组合生成最终的ID,并返回ID return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; }protected long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; }protected long timeGen() { return System.currentTimeMillis(); } }
推荐阅读
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- ssh生成公钥秘钥
- Java内存泄漏分析系列之二(jstack生成的Thread|Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析)
- 15、IDEA学习系列之其他设置(生成javadoc、缓存和索引的清理等)
- javaweb|基于Servlet+jsp+mysql开发javaWeb学生成绩管理系统
- Java代码辅助效率工具Lombok(注解|Java代码辅助效率工具Lombok(注解,自动生成代码)
- python|python random使用方法
- 单片机|keil把源代码生成lib的方法
- 小程序|【自制壁纸生成器】2022新年壁纸领取,换一张手机壁纸,迎接2022叭~
- Python【习题】(随机生成激活码、优惠码、验证码)