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(); } }



    推荐阅读